diff --git a/.github/workflows/alpine_numpy2/Dockerfile.ci b/.github/workflows/alpine_numpy2/Dockerfile.ci deleted file mode 100644 index 6c468269e093..000000000000 --- a/.github/workflows/alpine_numpy2/Dockerfile.ci +++ /dev/null @@ -1,82 +0,0 @@ -FROM alpine:edge - -RUN apk add \ - apache-arrow-dev \ - armadillo-dev \ - basisu-dev \ - blosc-dev \ - brunsli-dev \ - ccache \ - cfitsio-dev \ - cmake \ - curl-dev \ - expat-dev \ - freexl-dev \ - gcc \ - g++ \ - geos-dev \ - giflib-dev \ - gnu-libiconv-dev \ - hdf5-dev \ - json-c-dev \ - kealib-dev \ - libaec-dev \ - libarchive-dev \ - libdeflate-dev \ - libgeotiff-dev \ - libheif-dev \ - libjpeg-turbo-dev \ - libjxl-dev \ - libkml-dev \ - libpng-dev \ - libpq-dev \ - librasterlite2-dev \ - libspatialite-dev \ - libtirpc-dev \ - libwebp-dev \ - libxml2-dev \ - libxslt-dev \ - linux-headers \ - lz4-dev \ - make \ - mariadb-connector-c-dev \ - netcdf-dev \ - odbc-cpp-wrapper-dev \ - ogdi-dev \ - openexr-dev \ - openjpeg-dev \ - openssl-dev \ - pcre2-dev \ - podofo-dev \ - poppler-dev \ - proj-dev \ - proj-util \ - py3-pip \ - py3-setuptools \ - python3-dev \ - qhull-dev \ - sfcgal-dev \ - snappy-dev \ - sqlite-dev \ - swig \ - tiledb-dev \ - tiff-dev \ - unixodbc-dev \ - xerces-c-dev \ - xz-dev \ - zlib-dev \ - zstd-dev - -# Commenting out those packages to be sure to test numpy 2.0.0 -# py3-numpy \ -# py3-numpy-dev \ -# py3-pyarrow \ -# py3-pyarrow-pyc \ - -# apache-arrow-dev actually comes with an embedded pyarrow version, which is not py3-pyarrow, and is non functional ! -RUN mv /usr/lib/python3.12/site-packages/pyarrow /usr/lib/python3.12/site-packages/pyarrow.disabled - -COPY requirements.txt /tmp/ -RUN python3 -m pip install --break-system-packages numpy==2.0.0 -RUN python3 -m pip install --break-system-packages -U -r /tmp/requirements.txt - diff --git a/.github/workflows/alpine_numpy2/build.sh b/.github/workflows/alpine_numpy2/build.sh deleted file mode 100755 index 9cbdfc622841..000000000000 --- a/.github/workflows/alpine_numpy2/build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -set -e - -cat << EOF > /tmp/foo.cpp -#include -extern "C" void DeclareDeferredFOO(void); -void DeclareDeferredFOO() -{ - FILE* f = fopen("/tmp/DeclareDeferredFOO_has_been_run.bin", "wb"); - if (f) - fclose(f); -} -EOF - -cmake ${GDAL_SOURCE_DIR:=..} \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_UNITY_BUILD=ON \ - -DUSE_CCACHE=ON \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DIconv_INCLUDE_DIR=/usr/include/gnu-libiconv \ - -DIconv_LIBRARY=/usr/lib/libiconv.so \ - -DADD_EXTERNAL_DEFERRED_PLUGIN_FOO=/tmp/foo.cpp \ - -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS="-std=c++23 -Werror" -DWERROR_DEV_FLAG="-Werror=dev" -make -j$(nproc) -make -j$(nproc) install DESTDIR=/tmp/install-gdal - -# To check if DeclareDeferredFOO() is called by GDALAllRegister() -apps/gdalinfo --version - -if test -f /tmp/DeclareDeferredFOO_has_been_run.bin; then - echo "DeclareDeferredFOO() has been run" -else - echo "DeclareDeferredFOO() has NOT been run" - exit 1 -fi diff --git a/.github/workflows/android_cmake.yml b/.github/workflows/android_cmake.yml index 0200112eeaf1..2424254339c7 100644 --- a/.github/workflows/android_cmake.yml +++ b/.github/workflows/android_cmake.yml @@ -4,12 +4,14 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -24,10 +26,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache with: path: | diff --git a/.github/workflows/android_cmake/start.sh b/.github/workflows/android_cmake/start.sh index 4b275f01a3af..e7e6a090c4e1 100755 --- a/.github/workflows/android_cmake/start.sh +++ b/.github/workflows/android_cmake/start.sh @@ -88,6 +88,10 @@ PKG_CONFIG_LIBDIR=/tmp/install/lib/pkgconfig cmake .. \ -DSFCGAL_CONFIG=disabled \ -DHDF5_C_COMPILER_EXECUTABLE=disabled \ -DHDF5_CXX_COMPILER_EXECUTABLE=disabled + +echo "Check that GDAL_ENABLE_ARM_NEON_OPTIMIZATIONS:BOOL=ON" +(grep "GDAL_ENABLE_ARM_NEON_OPTIMIZATIONS:BOOL=ON" CMakeCache.txt > /dev/null && echo "yes") || (echo "Missing" && /bin/false) + make -j$(nproc) make install cd .. diff --git a/.github/workflows/auto_tag_stable.yml b/.github/workflows/auto_tag_stable.yml new file mode 100644 index 000000000000..71f005635758 --- /dev/null +++ b/.github/workflows/auto_tag_stable.yml @@ -0,0 +1,47 @@ +name: Update Stable Tag + +on: + push: + branches: + - '**' # Matches all branches, but we later filter on the one matching the STABLE_BRANCH repository variable + +permissions: + contents: read + +jobs: + update-stable-tag: + runs-on: ubuntu-latest + if: github.repository == 'OSGeo/GDAL' + permissions: + contents: write + steps: + - name: Check branch match + id: check_branch + env: + STABLE_BRANCH: ${{ vars.STABLE_BRANCH }} # Repository variable + run: | + echo "Push detected on branch $GITHUB_REF" + if [[ "${GITHUB_REF#refs/heads/}" != "${STABLE_BRANCH}" ]]; then + echo "This workflow only runs for branch $STABLE_BRANCH. Skipping further steps." + echo "run=false" >> $GITHUB_OUTPUT + else + echo "run=true" >> $GITHUB_OUTPUT + fi + + - name: Checkout code + if: steps.check_branch.outputs.run == 'true' + uses: actions/checkout@v4 + + - name: Tag + if: steps.check_branch.outputs.run == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config --global user.email "GDAL-bot@example.com" + git config --global user.name "GDAL-bot" + touch .dummy-file + git add .dummy-file + # Do that so that stable doesn't have the same git sha as the stable branch, so ReadTheDocs triggers a build + git commit -a -m "Add .dummy-file" + git checkout -b stable + git push -f origin stable diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 25ea0818bb79..218911710dd0 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -4,6 +4,7 @@ on: pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -31,7 +32,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/clang_static_analyzer.yml b/.github/workflows/clang_static_analyzer.yml index 452a8cd3c392..070b99a4f24b 100644 --- a/.github/workflows/clang_static_analyzer.yml +++ b/.github/workflows/clang_static_analyzer.yml @@ -1,15 +1,17 @@ -name: CLang Static Analyzer +name: Clang Static Analyzer on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -21,10 +23,10 @@ permissions: jobs: clang_static_analyzer: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Run - run: docker run --rm -v $PWD:$PWD ubuntu:22.04 sh -c "cd $PWD && apt update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends sudo software-properties-common && DEBIAN_FRONTEND=noninteractive sh ./ci/travis/csa_common/before_install.sh && sh ./ci/travis/csa_common/install.sh && sh ./ci/travis/csa_common/script.sh" + run: docker run --rm -v $PWD:$PWD ubuntu:24.04 sh -c "cd $PWD && apt update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends sudo software-properties-common && DEBIAN_FRONTEND=noninteractive sh ./ci/travis/csa_common/before_install.sh && sh ./ci/travis/csa_common/install.sh && sh ./ci/travis/csa_common/script.sh" diff --git a/.github/workflows/cmake_builds.yml b/.github/workflows/cmake_builds.yml index 2eee98263c9d..28f7dbb7cf4c 100644 --- a/.github/workflows/cmake_builds.yml +++ b/.github/workflows/cmake_builds.yml @@ -6,12 +6,15 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' + branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -32,9 +35,9 @@ jobs: cache-name: cmake-ubuntu-focal steps: - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache with: path: ${{ github.workspace }}/.ccache @@ -215,6 +218,8 @@ jobs: export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/install-gdal/lib $GITHUB_WORKSPACE/install-gdal/bin/gdalinfo --version PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/python3.8/site-packages python3 -c "from osgeo import gdal;print(gdal.VersionInfo(None))" + # Test fix for https://github.com/conda-forge/gdal-feedstock/issues/995 + PYTHONWARNINGS="error" PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/python3.8/site-packages python3 -c "from osgeo import gdal" PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/python3.8/site-packages python3 $GITHUB_WORKSPACE/scripts/check_doc.py - name: CMake with rpath run: | @@ -312,7 +317,7 @@ jobs: run: | git config --global core.autocrlf false - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install development packages uses: msys2/setup-msys2@ddf331adaebd714795f1042345e6ca57bd66cea8 # v2.24.1 with: @@ -327,7 +332,7 @@ jobs: mingw-w64-x86_64-libgeotiff mingw-w64-x86_64-libpng mingw-w64-x86_64-libtiff mingw-w64-x86_64-openjpeg2 mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-pytest mingw-w64-x86_64-python-setuptools mingw-w64-x86_64-python-lxml mingw-w64-x86_64-swig mingw-w64-x86_64-python-psutil mingw-w64-x86_64-blosc mingw-w64-x86_64-libavif - name: Setup cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache with: path: ${{ github.workspace }}\.ccache @@ -352,6 +357,7 @@ jobs: python -m pip install -r autotest/requirements.txt # Disable mySQL since C:/mysql/lib/mysqlclient.lib (unrelated to msys) is found, which causes linking issues # Set explicitly CMAKE_C|CXX_COMPILER otherwise C:/ProgramData/chocolatey/bin/gcc.exe would be used + # Disable GDAL_ENABLE_DRIVER_HDF5 because of https://github.com/OSGeo/gdal/issues/11181 - name: Configure run: | cmake -S . -B build -G "${generator}" -Werror=dev \ @@ -364,7 +370,8 @@ jobs: -DCMAKE_PREFIX_PATH=/mingw64 \ -DCMAKE_INSTALL_PREFIX=$PWD/install-gdal \ "-DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD}" \ - -DGDAL_USE_MYSQL:BOOL=OFF + -DGDAL_USE_MYSQL:BOOL=OFF \ + -DGDAL_ENABLE_DRIVER_HDF5=OFF working-directory: ${{ github.workspace }} - name: Build run: cmake --build build -j 3 @@ -405,7 +412,7 @@ jobs: run: | git config --global core.autocrlf false - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 - name: populate JAVA_HOME shell: pwsh @@ -414,7 +421,6 @@ jobs: - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3.0.4 with: activate-environment: gdalenv - miniforge-variant: Mambaforge miniforge-version: latest use-mamba: true auto-update-conda: true @@ -429,7 +435,7 @@ jobs: cfitsio freexl geotiff libjpeg-turbo libpq libspatialite libwebp-base pcre pcre2 postgresql \ sqlite tiledb zstd cryptopp cgal doxygen librttopo libkml openssl xz \ openjdk ant qhull armadillo blas blas-devel libblas libcblas liblapack liblapacke blosc libarchive \ - arrow-cpp pyarrow libaec libavif cmake + arrow-cpp pyarrow libaec libheif libavif cmake fsspec - name: Check CMake version shell: bash -l {0} run: | @@ -456,7 +462,7 @@ jobs: # Build PDF driver as plugin due to the PDFium build including libopenjp2 symbols which would conflict with external libopenjp2 run: | mkdir -p $GITHUB_WORKSPACE/build - cmake -G "${generator}" -Werror=dev "-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal" "-DUSE_CCACHE=ON" "-DCMAKE_PREFIX_PATH=${CONDA}/envs/gdalenv" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DGDAL_ENABLE_PLUGINS:BOOL=ON -DGDAL_ENABLE_PLUGINS_NO_DEPS:BOOL=ON -DGDAL_USE_PUBLICDECOMPWT:BOOL=ON -DPUBLICDECOMPWT_URL=https://github.com/rouault/PublicDecompWT -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=ON -DGDAL_USE_MYSQL:BOOL=OFF -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX" -DWERROR_DEV_FLAG="-Werror=dev" -DCMAKE_BUILD_TYPE=Release -DPDFIUM_ROOT=$GITHUB_WORKSPACE/install-pdfium -DGDAL_ENABLE_DRIVER_PDF_PLUGIN:BOOL=ON -DCMAKE_UNITY_BUILD=ON + cmake -G "${generator}" -Werror=dev "-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal" "-DUSE_CCACHE=ON" "-DCMAKE_PREFIX_PATH=${CONDA}/envs/gdalenv" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DGDAL_ENABLE_PLUGINS:BOOL=ON -DGDAL_ENABLE_PLUGINS_NO_DEPS:BOOL=ON -DGDAL_USE_PUBLICDECOMPWT:BOOL=ON -DPUBLICDECOMPWT_URL=https://github.com/rouault/PublicDecompWT -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=ON -DGDAL_USE_MYSQL:BOOL=OFF -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX" -DWERROR_DEV_FLAG="-Werror=dev" -DCMAKE_BUILD_TYPE=Release -DPDFIUM_ROOT=$GITHUB_WORKSPACE/install-pdfium -DGDAL_ENABLE_DRIVER_PDF_PLUGIN:BOOL=ON -DCMAKE_UNITY_BUILD=ON -DOGR_ENABLE_DRIVER_TAB_PLUGIN=OFF -DOGR_ENABLE_DRIVER_GEOJSON_PLUGIN=OFF - name: Build shell: bash -l {0} run: cmake --build $GITHUB_WORKSPACE/build --config Release -j 2 @@ -485,6 +491,17 @@ jobs: PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/site-packages python -c "from osgeo import gdal;print(gdal.VersionInfo(None))" export PATH=$GITHUB_WORKSPACE/install-gdal/Scripts:$PATH PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/site-packages gdal_edit --version + - name: Check the build includes the expected drivers + shell: bash -l {0} + run: | + export PATH=$GITHUB_WORKSPACE/install-gdal/bin:$PATH + gdalinfo --formats > found_formats.txt + ogrinfo --formats >> found_formats.txt + cat found_formats.txt + cat $GITHUB_WORKSPACE/.github/workflows/windows_conda_expected_gdalinfo_formats.txt $GITHUB_WORKSPACE/.github/workflows/windows_conda_expected_ogrinfo_formats.txt > expected_formats.txt + dos2unix expected_formats.txt + dos2unix found_formats.txt + diff -u expected_formats.txt found_formats.txt - name: Show gdal.pc shell: bash -l {0} run: cat $GITHUB_WORKSPACE/build/gdal.pc @@ -507,11 +524,10 @@ jobs: run: | git config --global core.autocrlf false - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3.0.4 with: activate-environment: gdalenv - miniforge-variant: Mambaforge miniforge-version: latest use-mamba: true auto-update-conda: true @@ -541,7 +557,15 @@ jobs: shell: bash -l {0} run: | rm -f build/CMakeCache.txt - cmake -A ${architecture} -G "${generator}" "-DCMAKE_PREFIX_PATH=${CONDA}/envs/gdalenv" -Werror=dev "-DCMAKE_CXX_COMPILER_LAUNCHER=clcache" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX" -DGDAL_USE_EXTERNAL_LIBS:BOOL=OFF -DGDAL_USE_PNG_INTERNAL=OFF -DGDAL_USE_JPEG_INTERNAL=OFF -DGDAL_USE_JPEG12_INTERNAL=OFF -DGDAL_USE_GIF_INTERNAL=OFF -DGDAL_USE_LERC_INTERNAL=OFF -DGDAL_USE_LERCV1_INTERNAL=OFF -DGDAL_USE_QHULL_INTERNAL=OFF -DGDAL_USE_OPENCAD_INTERNAL=OFF -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF -DOGR_BUILD_OPTIONAL_DRIVERS=OFF -DWERROR_DEV_FLAG="-Werror=dev" + cmake -A ${architecture} -G "${generator}" "-DCMAKE_PREFIX_PATH=${CONDA}/envs/gdalenv" -Werror=dev "-DCMAKE_CXX_COMPILER_LAUNCHER=clcache" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX" -DGDAL_USE_EXTERNAL_LIBS:BOOL=OFF -DGDAL_USE_PNG_INTERNAL=OFF -DGDAL_USE_JPEG_INTERNAL=OFF -DGDAL_USE_JPEG12_INTERNAL=OFF -DGDAL_USE_GIF_INTERNAL=OFF -DGDAL_USE_LERC_INTERNAL=OFF -DGDAL_USE_LERCV1_INTERNAL=OFF -DGDAL_USE_QHULL_INTERNAL=OFF -DGDAL_USE_OPENCAD_INTERNAL=OFF -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF -DOGR_BUILD_OPTIONAL_DRIVERS=OFF -DGDAL_ENABLE_DRIVER_DERIVED=ON -DWERROR_DEV_FLAG="-Werror=dev" + - name: Build + shell: bash -l {0} + run: cmake --build $GITHUB_WORKSPACE/build --config RelWithDebInfo -j 2 + + - name: Re-enable shapefile driver (otherwise lots of python tests would fail) + shell: bash -l {0} + run: | + cmake -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DOGR_ENABLE_DRIVER_SHAPE=ON -DOGR_ENABLE_DRIVER_SHAPE_PLUGIN=ON - name: Build shell: bash -l {0} run: cmake --build $GITHUB_WORKSPACE/build --config RelWithDebInfo -j 2 @@ -582,11 +606,11 @@ jobs: - name: Setup xcode uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0 with: - xcode-version: 14.3 + xcode-version: '15.4.0' - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache with: path: ${{ github.workspace }}/.ccache @@ -601,7 +625,26 @@ jobs: rm -rf /opt/homebrew/lib/node_modules # conflicts with node@18 from brew brew update brew outdated - brew unlink python + # Attempt at fixing: + # => Pouring pkgconf--2.3.0_1.arm64_sonoma.bottle.tar.gz + # Error: The `brew link` step did not complete successfully + # The formula built, but is not symlinked into /opt/homebrew + # Could not symlink bin/pkg-config + # Target /opt/homebrew/bin/pkg-config + # is a symlink belonging to pkg-config@0.29.2. You can unlink it: + # brew unlink pkg-config@0.29.2 + # + # To force the link and overwrite all conflicting files: + # brew link --overwrite pkgconf + # + # To list all files that would be deleted: + # brew link --overwrite pkgconf --dry-run + # + # Possible conflicting files are: + # /opt/homebrew/bin/pkg-config -> /opt/homebrew/Cellar/pkg-config@0.29.2/0.29.2_3/bin/pkg-config + # /opt/homebrew/share/aclocal/pkg.m4 -> /opt/homebrew/Cellar/pkg-config@0.29.2/0.29.2_3/share/aclocal/pkg.m4 + # /opt/homebrew/share/man/man1/pkg-config.1 -> /opt/homebrew/Cellar/pkg-config@0.29.2/0.29.2_3/share/man/man1/pkg-config.1 + rm -f /opt/homebrew/bin/pkg-config /opt/homebrew/share/aclocal/pkg.m4 /opt/homebrew/share/man/man1/pkg-config.1 brew install --overwrite python@3.11 python@3.12 brew install postgresql || brew link postgresql brew install pkg-config freexl libxml2 libspatialite geos proj libgeotiff openjpeg giflib libaec postgis poppler doxygen unixodbc jpeg-turbo aom jpeg-xl libheif libarchive libkml boost @@ -609,6 +652,8 @@ jobs: brew link --force sqlite # gdal is automatically installed as a dependency for postgis brew uninstall --ignore-dependencies gdal + # Workaround for https://github.com/Homebrew/homebrew-core/pull/170959#issuecomment-2379606442 + sed -i .bak 's/hdf5_hl;hdf5;/hdf5_hl-shared;hdf5-shared;/g' "$(brew --prefix netcdf)/lib/cmake/netCDF/netCDFTargets.cmake" - name: Configure ccache run: | echo CCACHE_BASEDIR=$PWD >> ${GITHUB_ENV} @@ -664,7 +709,7 @@ jobs: run: | git config --global core.autocrlf false - name: Checkout GDAL - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3.0.4 with: activate-environment: gdalenv diff --git a/.github/workflows/code_checks.yml b/.github/workflows/code_checks.yml index 905cbdb2a0ab..3b2fbf0ee127 100644 --- a/.github/workflows/code_checks.yml +++ b/.github/workflows/code_checks.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install Requirements run: | @@ -47,7 +47,7 @@ jobs: container: ubuntu:24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install Requirements run: | @@ -65,11 +65,45 @@ jobs: cd build ../scripts/cppcheck.sh + cppcheck_master: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - name: Install Requirements + run: | + sudo apt update + sudo apt install -y git libsqlite3-dev ccache sqlite3 libproj-dev cmake g++ make + + - name: Build cppcheck + run: | + git clone https://github.com/danmar/cppcheck + cd cppcheck + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make -j$(nproc) + sudo make install + cd ../.. + + - name: Run cmake + run: | + mkdir build + cd build + cmake .. + + - name: Run cppcheck test + run: | + cd build + # Do not fail the job. This is just used as a tool to monitor how we are regarding recent cppcheck + ../scripts/cppcheck.sh || /bin/true + code_quality_checks: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Detect tabulations run: ./scripts/detect_tabulations.sh @@ -110,7 +144,7 @@ jobs: sudo apt-get install -y python3 coreutils - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Detect binary files run: python3 ./scripts/check_binaries.py @@ -118,8 +152,8 @@ jobs: linting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 doxygen: @@ -127,7 +161,7 @@ jobs: container: ghcr.io/osgeo/proj-docs steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Run doxygen run: | @@ -138,12 +172,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install Requirements run: | sudo apt install python3-pip wget - sudo pip3 install cffconvert + # ruamel.yaml.clib 0.2.9 throws a 'TypeError: a string or stream input is required' when running cffconvert --validate + sudo pip3 install cffconvert "ruamel.yaml.clib<0.2.9" - name: Validate citation file run: | @@ -157,9 +192,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: 3.8 - name: Install lint tool @@ -173,7 +208,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install requirements run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f5ec912d4502..f26c7e499044 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,12 +4,14 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -44,7 +46,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Install dependencies run: | @@ -107,7 +109,7 @@ jobs: # We do that after running CMake to avoid CodeQL to trigger during CMake time, # in particular during HDF5 detection which is terribly slow (https://github.com/OSGeo/gdal/issues/9549) - name: Initialize CodeQL - uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 + uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -127,6 +129,6 @@ jobs: cmake --build build -j$(nproc) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 + uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/conda.yml b/.github/workflows/conda.yml index b56b3a04b708..4ef81cea9244 100644 --- a/.github/workflows/conda.yml +++ b/.github/workflows/conda.yml @@ -4,6 +4,7 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' @@ -37,21 +38,20 @@ jobs: CACHE_NUMBER: 0 steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Support longpaths run: git config --system core.longpaths true if: matrix.platform == 'windows-latest' - name: Cache Conda Environment - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ~/conda_pkgs_dir key: ${{ runner.os }}-${{ steps.get-date.outputs.today }}-conda-${{ env.CACHE_NUMBER }} - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3.0.4 with: - #miniforge-variant: Mambaforge miniforge-version: latest use-mamba: true channels: conda-forge @@ -74,7 +74,7 @@ jobs: source ../ci/travis/conda/compile.sh working-directory: ./gdal-feedstock - - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: ${{ matrix.platform }}-conda-package path: ./gdal-feedstock/packages/ diff --git a/.github/workflows/coverity_scan.yml b/.github/workflows/coverity_scan.yml index 746b7864a198..961177d2e54b 100644 --- a/.github/workflows/coverity_scan.yml +++ b/.github/workflows/coverity_scan.yml @@ -43,7 +43,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to GHCR if: env.CONTAINER_REGISTRY == 'ghcr.io' diff --git a/.github/workflows/coverity_scan/build.sh b/.github/workflows/coverity_scan/build.sh index 3becfb98f422..596bbbc100a9 100755 --- a/.github/workflows/coverity_scan/build.sh +++ b/.github/workflows/coverity_scan/build.sh @@ -22,10 +22,33 @@ cmake ${GDAL_SOURCE_DIR:=..} \ /tmp/cov-analysis-linux64/bin/cov-build --dir cov-int make "-j$(nproc)" tar czf cov-int.tgz cov-int -curl \ - --form token=$COVERITY_SCAN_TOKEN \ - --form email=$COVERITY_SCAN_EMAIL \ - --form file=@cov-int.tgz \ - --form version=master \ - --form description="`git rev-parse --abbrev-ref HEAD` `git rev-parse --short HEAD`" \ - https://scan.coverity.com/builds?project=GDAL + +apt-get update -y +apt-get install -y jq + +## Below from https://scan.coverity.com/projects/gdal/builds/new + +# Initialize a build. Fetch a cloud upload url. +curl -X POST \ + -d version=master \ + -d description="$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short HEAD)" \ + -d token=$COVERITY_SCAN_TOKEN \ + -d email=$COVERITY_SCAN_EMAIL \ + -d file_name="cov-int.tgz" \ + https://scan.coverity.com/projects/749/builds/init \ + | tee response + +# Store response data to use in later stages. +upload_url=$(jq -r '.url' response) +build_id=$(jq -r '.build_id' response) + +# Upload the tarball to the Cloud. +curl -X PUT \ + --header 'Content-Type: application/json' \ + --upload-file cov-int.tgz \ + $upload_url + +# Trigger the build on Scan. +curl -X PUT \ + -d token=$COVERITY_SCAN_TOKEN \ + https://scan.coverity.com/projects/749/builds/$build_id/enqueue diff --git a/.github/workflows/delete_untagged_containers.yml b/.github/workflows/delete_untagged_containers.yml index 5d62429e8f32..e37a0012c1c4 100644 --- a/.github/workflows/delete_untagged_containers.yml +++ b/.github/workflows/delete_untagged_containers.yml @@ -4,6 +4,7 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' diff --git a/.github/workflows/doc_checks.yml b/.github/workflows/doc_checks.yml index 4487f53bb683..545cb4eb5375 100644 --- a/.github/workflows/doc_checks.yml +++ b/.github/workflows/doc_checks.yml @@ -24,7 +24,7 @@ jobs: container: ghcr.io/osgeo/proj-docs steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Setup environment shell: bash -l {0} run: | @@ -39,7 +39,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ - -DBUILD_APPS=OFF \ + -DBUILD_APPS=ON \ -DBUILD_TESTING=OFF \ -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \ -DOGR_BUILD_OPTIONAL_DRIVERS=OFF @@ -56,6 +56,11 @@ jobs: ldconfig popd + - name: Update components + shell: bash -l {0} + run: | + pip install -U "sphinx-rtd-theme>=3.0.0" "sphinxcontrib-spelling>=8.0.0" + - name: Print versions shell: bash -l {0} run: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000000..7b34b00db0f2 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,58 @@ +name: Docker + +on: + pull_request: + paths: + - 'docker/**' + - '.github/workflows/docker.yml' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + + docker_builds: + + strategy: + fail-fast: false + matrix: + include: + - name: alpine-small + arch: linux/amd64 + + - name: alpine-normal + arch: linux/amd64 + + - name: ubuntu-small + arch: linux/amd64 + + - name: ubuntu-small + arch: linux/arm64 + + - name: ubuntu-full + arch: linux/amd64 + + - name: ubuntu-full + arch: linux/arm64 + + name: ${{ matrix.name }}-${{ matrix.arch }} + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - name: Build + shell: bash -l {0} + run: | + docker run --rm --privileged linuxkit/binfmt:v0.8 + cd docker/${{ matrix.name }} + ./build.sh --platform ${{ matrix.arch }} diff --git a/.github/workflows/fedora_rawhide/build.sh b/.github/workflows/fedora_rawhide/build.sh index b4d22a77b2b9..423a817451cc 100755 --- a/.github/workflows/fedora_rawhide/build.sh +++ b/.github/workflows/fedora_rawhide/build.sh @@ -10,7 +10,17 @@ cmake ${GDAL_SOURCE_DIR:=..} \ -DCMAKE_CXX_FLAGS="-std=c++20 -Werror -O1 -D_FORTIFY_SOURCE=2" \ -DCMAKE_SHARED_LINKER_FLAGS="-lstdc++" \ -DUSE_CCACHE=ON \ + -DEMBED_RESOURCE_FILES=ON \ -DCMAKE_INSTALL_PREFIX=/usr \ -DWERROR_DEV_FLAG="-Werror=dev" make -j$(nproc) make -j$(nproc) install DESTDIR=/tmp/install-gdal + +ctest -V -j $(nproc) + +rm -rf data +cmake ${GDAL_SOURCE_DIR:=..} \ + -DUSE_ONLY_EMBEDDED_RESOURCE_FILES=ON +rm -rf /tmp/install-gdal +make -j$(nproc) +make -j$(nproc) install DESTDIR=/tmp/install-gdal diff --git a/.github/workflows/linux_build.yml b/.github/workflows/linux_build.yml index a37ac426e445..72807eda42c0 100644 --- a/.github/workflows/linux_build.yml +++ b/.github/workflows/linux_build.yml @@ -4,12 +4,14 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -65,12 +67,6 @@ jobs: build_script: build.sh os: ubuntu-22.04 - - name: Alpine, numpy 2 - id: alpine_numpy2 - container: alpine_numpy2 - build_script: build.sh - os: ubuntu-22.04 - - name: Alpine, clang 32-bit id: alpine_32bit container: alpine_32bit @@ -174,7 +170,7 @@ jobs: sudo sysctl vm.mmap_rnd_bits=28 - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to Docker Hub if: env.CONTAINER_REGISTRY == 'docker.io' @@ -241,7 +237,7 @@ jobs: # different architecture. - name: Restore build cache id: restore-cache - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ${{ github.workspace }}/.ccache key: ${{ matrix.id }}-${{ steps.get-arch.outputs.arch }}-${{ github.ref_name }}-${{ github.run_id }} @@ -262,6 +258,10 @@ jobs: # FIXME the default BUILD_CMD here isn't working...we get an error # about the quotes not matching. - name: Build + env: + TRAVIS: yes + TRAVIS_BRANCH: ${{ matrix.travis_branch }} + BUILD_NAME: ${{ matrix.travis_branch }} run: | if test -f ".github/workflows/${{ matrix.id }}/${{ matrix.build_script }}"; then BUILD_CMD="$(pwd)/.github/workflows/${{ matrix.id }}/${{ matrix.build_script }}" @@ -269,11 +269,20 @@ jobs: BUILD_CMD="sh -c 'cmake .. && make -j$(nproc)'" fi + # For cache + mkdir -p .gdal + mkdir -p build-${{ matrix.id }} docker run --name gdal-build \ --rm \ + -e CI \ + -e GITHUB_WORKFLOW \ + -e TRAVIS \ + -e TRAVIS_BRANCH \ + -e BUILD_NAME \ -e "GDAL_SOURCE_DIR=$(pwd)" \ -u $(id -u ${USER}):$(id -g ${USER}) \ + -v $(pwd)/.gdal:/.gdal:rw \ -v $(pwd):$(pwd):rw \ -v ${{ github.workspace }}/.ccache:/.ccache:rw \ --workdir $(pwd)/build-${{ matrix.id }} \ @@ -289,7 +298,7 @@ jobs: ccache -s - name: Save build cache - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ${{ github.workspace }}/.ccache key: ${{ steps.restore-cache.outputs.cache-primary-key }} @@ -320,7 +329,7 @@ jobs: fi # For cache - mkdir .gdal + mkdir -p .gdal docker run \ -e CI \ @@ -340,7 +349,7 @@ jobs: ${TEST_CMD} - name: Coveralls - uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63 # v2.3.0 + uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 # v2.3.4 if: ${{ matrix.id == 'coverage' }} with: format: lcov @@ -355,14 +364,14 @@ jobs: docker push ${CONTAINER_NAME_FULL} - name: Upload coverage artifacts - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 if: ${{ matrix.id == 'coverage' }} with: name: coverage_index.html path: build-${{ matrix.id }}/coverage_html/index.html - name: Upload coverage artifacts - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 if: ${{ matrix.id == 'coverage' }} with: name: HTML diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2221d7e29664..31f680caaa15 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -4,12 +4,14 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -25,7 +27,7 @@ jobs: runs-on: macos-14 steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3.0.4 with: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ff20b36ef31f..b1342e321fab 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -36,7 +36,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: persist-credentials: false @@ -63,7 +63,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/slow_tests.yml b/.github/workflows/slow_tests.yml index f7cec9357de0..e723f8aa9f23 100644 --- a/.github/workflows/slow_tests.yml +++ b/.github/workflows/slow_tests.yml @@ -47,7 +47,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Login to GHCR if: env.CONTAINER_REGISTRY == 'ghcr.io' @@ -107,7 +107,7 @@ jobs: # different architecture. - name: Restore build cache id: restore-cache - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ${{ github.workspace }}/.ccache key: ${{ matrix.id }}-${{ steps.get-arch.outputs.arch }}-${{ github.ref_name }}-${{ github.run_id }} @@ -147,7 +147,7 @@ jobs: ccache -s - name: Save build cache - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ${{ github.workspace }}/.ccache key: ${{ steps.restore-cache.outputs.cache-primary-key }} diff --git a/.github/workflows/ubuntu_22.04/services.sh b/.github/workflows/ubuntu_22.04/services.sh index d4d9c002aa2c..19fe9c62404a 100755 --- a/.github/workflows/ubuntu_22.04/services.sh +++ b/.github/workflows/ubuntu_22.04/services.sh @@ -7,9 +7,9 @@ set -ex ################## # MSSQL: server side -docker rm -f gdal-sql1 -docker pull mcr.microsoft.com/mssql/server:2017-latest -docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=DummyPassw0rd' -p 1433:1433 --name gdal-sql1 -d mcr.microsoft.com/mssql/server:2017-latest +#docker rm -f gdal-sql1 +#docker pull mcr.microsoft.com/mssql/server:2017-latest +#docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=DummyPassw0rd' -p 1433:1433 --name gdal-sql1 -d mcr.microsoft.com/mssql/server:2017-latest # MySQL 8 docker rm -f gdal-mysql1 @@ -38,7 +38,7 @@ docker run --name gdal-mongo -p 27018:27017 -d mongo:4.4 sleep 10 # MSSQL -docker exec -t gdal-sql1 /opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -U SA -P DummyPassw0rd -Q "CREATE DATABASE TestDB" +#docker exec -t gdal-sql1 /opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -U SA -P DummyPassw0rd -Q "CREATE DATABASE TestDB" # MySQL docker exec gdal-mysql1 sh -c "echo 'CREATE DATABASE test; SELECT Version()' | mysql -uroot -ppasswd" diff --git a/.github/workflows/ubuntu_22.04/test.sh b/.github/workflows/ubuntu_22.04/test.sh index 9af1dd53f7b7..8bcc8b27ba80 100755 --- a/.github/workflows/ubuntu_22.04/test.sh +++ b/.github/workflows/ubuntu_22.04/test.sh @@ -31,6 +31,6 @@ AZURE_STORAGE_CONNECTION_STRING=${AZURITE_STORAGE_CONNECTION_STRING} python3 -c # MongoDB v3 (cd autotest && MONGODBV3_TEST_PORT=27018 MONGODBV3_TEST_HOST=$IP $PYTEST ogr/ogr_mongodbv3.py) -(cd autotest && OGR_MSSQL_CONNECTION_STRING="MSSQL:server=$IP;database=TestDB;driver=ODBC Driver 17 for SQL Server;UID=SA;PWD=DummyPassw0rd" $PYTEST ogr/ogr_mssqlspatial.py) +#(cd autotest && OGR_MSSQL_CONNECTION_STRING="MSSQL:server=$IP;database=TestDB;driver=ODBC Driver 17 for SQL Server;UID=SA;PWD=DummyPassw0rd" $PYTEST ogr/ogr_mssqlspatial.py) (cd autotest && $PYTEST) diff --git a/.github/workflows/ubuntu_24.04/Dockerfile.ci b/.github/workflows/ubuntu_24.04/Dockerfile.ci index 213d1a36069a..688996f59be8 100644 --- a/.github/workflows/ubuntu_24.04/Dockerfile.ci +++ b/.github/workflows/ubuntu_24.04/Dockerfile.ci @@ -73,6 +73,16 @@ RUN apt-get update && \ wget \ zip +# temporary libheif build +RUN apt-get install -y --allow-unauthenticated libaom-dev libbrotli-dev libde265-dev libx265-dev +RUN git clone --depth 1 https://github.com/strukturag/libheif.git libheif-git && \ + cd libheif-git && \ + mkdir build && \ + cd build && \ + cmake --preset=develop .. && \ + make -j$(nproc) && \ + make install + # MSSQL: client side RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - RUN curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/msprod.list @@ -148,3 +158,25 @@ RUN python3 -m pip install -U --break-system-packages -r /tmp/requirements.txt # cfchecker requires udunits2 RUN apt-get install -y --allow-unauthenticated libudunits2-0 libudunits2-data RUN python3 -m pip install --break-system-packages cfchecker + +RUN python3 -m pip install --break-system-packages fsspec + +# Manually install ADBC packages from Ubuntu 22.04 as there are no 24.04 packages at time of writing. +RUN curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake-dev_14-1_amd64.deb + +# Install libduckdb +RUN curl -LO -fsS https://github.com/duckdb/duckdb/releases/download/v1.1.3/libduckdb-linux-amd64.zip \ + && unzip libduckdb-linux-amd64.zip libduckdb.so \ + && mv libduckdb.so /usr/lib/x86_64-linux-gnu \ + && rm -f libduckdb-linux-amd64.zip diff --git a/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt b/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt new file mode 100644 index 000000000000..396d0730f97e --- /dev/null +++ b/.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt @@ -0,0 +1,158 @@ +Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) + VRT -raster,multidimensional raster- (rw+v): Virtual Raster (*.vrt) + DERIVED -raster- (ro): Derived datasets using VRT pixel functions + GTI -raster- (rov): GDAL Raster Tile Index (*.gti.gpkg, *.gti.fgb, *.gti) + SNAP_TIFF -raster- (rov): Sentinel Application Processing GeoTIFF + GTiff -raster- (rw+vs): GeoTIFF (*.tif, *.tiff) + COG -raster- (wv): Cloud optimized GeoTIFF generator (*.tif, *.tiff) + NITF -raster- (rw+vs): National Imagery Transmission Format (*.ntf) + RPFTOC -raster- (rovs): Raster Product Format TOC format (*.toc) + ECRGTOC -raster- (rovs): ECRG TOC format (*.xml) + HFA -raster- (rw+v): Erdas Imagine Images (.img) (*.img) + SAR_CEOS -raster- (rov): CEOS SAR Image + CEOS -raster- (rov): CEOS Image + JAXAPALSAR -raster- (rov): JAXA PALSAR Product Reader (Level 1.1/1.5) + GFF -raster- (rov): Ground-based SAR Applications Testbed File Format (.gff) (*.gff) + ELAS -raster- (rw+v): ELAS + ESRIC -raster- (rov): Esri Compact Cache (*.json, *.tpkx) + AIG -raster- (rov): Arc/Info Binary Grid + AAIGrid -raster- (rwv): Arc/Info ASCII Grid (*.asc) + GRASSASCIIGrid -raster- (rov): GRASS ASCII Grid + ISG -raster- (rov): International Service for the Geoid (*.isg) + SDTS -raster- (rov): SDTS Raster (*.ddf) + DTED -raster- (rwv): DTED Elevation Raster (*.dt0, *.dt1, *.dt2) + PNG -raster- (rwv): Portable Network Graphics (*.png) + JPEG -raster- (rwv): JPEG JFIF (*.jpg, *.jpeg) + MEM -raster,multidimensional raster- (rw+): In Memory Raster + JDEM -raster- (rov): Japanese DEM (.mem) (*.mem) + GIF -raster- (rwv): Graphics Interchange Format (.gif) (*.gif) + BIGGIF -raster- (rov): Graphics Interchange Format (.gif) (*.gif) + ESAT -raster- (rov): Envisat Image Format (*.n1) + FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) + BSB -raster- (rov): Maptech BSB Nautical Charts (*.kap) + XPM -raster- (rwv): X11 PixMap Format (*.xpm) + BMP -raster- (rw+v): MS Windows Device Independent Bitmap (*.bmp) + DIMAP -raster- (rovs): SPOT DIMAP + AirSAR -raster- (rov): AirSAR Polarimetric Image + RS2 -raster- (rovs): RadarSat 2 XML Product + SAFE -raster- (rov): Sentinel-1 SAR SAFE Product + PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + PCRaster -raster- (rw+): PCRaster Raster File (*.map) + ILWIS -raster- (rw+v): ILWIS Raster Map (*.mpr, *.mpl) + SGI -raster- (rw+v): SGI Image File Format 1.0 (*.rgb) + SRTMHGT -raster- (rwv): SRTMHGT File Format (*.hgt) + Leveller -raster- (rw+v): Leveller heightfield (*.ter) + Terragen -raster- (rw+v): Terragen heightfield (*.ter) + netCDF -raster,multidimensional raster,vector- (rw+vs): Network Common Data Format (*.nc) + HDF4 -raster,multidimensional raster- (ros): Hierarchical Data Format Release 4 (*.hdf) + HDF4Image -raster- (rw+): HDF4 Dataset + ISIS3 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 3) (*.lbl, *.cub) + ISIS2 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 2) + PDS -raster- (rov): NASA Planetary Data System + PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + VICAR -raster,vector- (rw+v): MIPL VICAR file + TIL -raster- (rov): EarthWatch .TIL + ERS -raster- (rw+v): ERMapper .ers Labelled (*.ers) + JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) + L1B -raster- (rovs): NOAA Polar Orbiter Level 1b Data Set + FIT -raster- (rwv): FIT Image + GRIB -raster,multidimensional raster- (rwv): GRIdded Binary (.grb, .grb2) (*.grb, *.grb2, *.grib2) + RMF -raster- (rw+v): Raster Matrix Format (*.rsw) + WCS -raster- (rovs): OGC Web Coverage Service + WMS -raster- (rwvs): OGC Web Map Service + MSGN -raster- (rov): EUMETSAT Archive native (.nat) (*.nat) + RST -raster- (rw+v): Idrisi Raster A.1 (*.rst) + GSAG -raster- (rwv): Golden Software ASCII Grid (.grd) (*.grd) + GSBG -raster- (rw+v): Golden Software Binary Grid (.grd) (*.grd) + GS7BG -raster- (rw+v): Golden Software 7 Binary Grid (.grd) (*.grd) + COSAR -raster- (rov): COSAR Annotated Binary Matrix (TerraSAR-X) + TSX -raster- (rov): TerraSAR-X Product + COASP -raster- (ro): DRDC COASP SAR Processor Raster (*.hdr) + R -raster- (rwv): R Object Data Store (*.rda) + MAP -raster- (rov): OziExplorer .MAP + KMLSUPEROVERLAY -raster- (rwv): Kml Super Overlay (*.kml, *.kmz) + WEBP -raster- (rwv): WEBP (*.webp) + PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + Rasterlite -raster- (rwvs): Rasterlite (*.sqlite) + MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) + PLMOSAIC -raster- (ro): Planet Labs Mosaics API + CALS -raster- (rwv): CALS (Type 1) (*.cal, *.ct1) + WMTS -raster- (rwv): OGC Web Map Tile Service + SENTINEL2 -raster- (rovs): Sentinel 2 + MRF -raster- (rw+v): Meta Raster Format (*.mrf) + PNM -raster- (rw+v): Portable Pixmap Format (netpbm) (*.pgm, *.ppm, *.pnm) + DOQ1 -raster- (rov): USGS DOQ (Old Style) + DOQ2 -raster- (rov): USGS DOQ (New Style) + PAux -raster- (rw+v): PCI .aux Labelled + MFF -raster- (rw+v): Vexcel MFF Raster (*.hdr) + MFF2 -raster- (rw+): Vexcel MFF2 (HKV) Raster + GSC -raster- (rov): GSC Geogrid + FAST -raster- (rov): EOSAT FAST Format + BT -raster- (rw+v): VTP .bt (Binary Terrain) 1.3 Format (*.bt) + LAN -raster- (rw+v): Erdas .LAN/.GIS + CPG -raster- (rov): Convair PolGASP + NDF -raster- (rov): NLAPS Data Format + EIR -raster- (rov): Erdas Imagine Raw + DIPEx -raster- (rov): DIPEx + LCP -raster- (rwv): FARSITE v.4 Landscape File (.lcp) (*.lcp) + GTX -raster- (rw+v): NOAA Vertical Datum .GTX (*.gtx) + LOSLAS -raster- (rov): NADCON .los/.las Datum Grid Shift + NTv2 -raster- (rw+vs): NTv2 Datum Grid Shift (*.gsb, *.gvb) + CTable2 -raster- (rw+v): CTable2 Datum Grid Shift + ACE2 -raster- (rov): ACE2 (*.ACE2) + SNODAS -raster- (rov): Snow Data Assimilation System (*.hdr) + KRO -raster- (rw+v): KOLOR Raw (*.kro) + ROI_PAC -raster- (rw+v): ROI_PAC raster + RRASTER -raster- (rw+v): R Raster (*.grd) + BYN -raster- (rw+v): Natural Resources Canada's Geoid (*.byn, *.err) + NOAA_B -raster- (rov): NOAA GEOCON/NADCON5 .b format (*.b) + NSIDCbin -raster- (rov): NSIDC Sea Ice Concentrations binary (.bin) (*.bin) + RIK -raster- (rov): Swedish Grid RIK (.rik) (*.rik) + USGSDEM -raster- (rwv): USGS Optional ASCII DEM (and CDED) (*.dem) + GXF -raster- (rov): GeoSoft Grid Exchange Format (*.gxf) + BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) + S102 -raster,multidimensional raster- (rovs): S-102 Bathymetric Surface Product (*.h5) + S104 -raster,multidimensional raster- (rov): S-104 Water Level Information for Surface Navigation Product (*.h5) + S111 -raster,multidimensional raster- (rov): Surface Currents Product (*.h5) + HDF5 -raster,multidimensional raster- (rovs): Hierarchical Data Format Release 5 (*.h5, *.hdf5) + HDF5Image -raster- (rov): HDF5 Dataset + NWT_GRD -raster- (rw+v): Northwood Numeric Grid Format .grd/.tab (*.grd) + NWT_GRC -raster- (rov): Northwood Classified Grid Format .grc/.tab (*.grc) + ADRG -raster- (rw+vs): ARC Digitized Raster Graphics (*.gen) + SRP -raster- (rovs): Standard Raster Product (ASRP/USRP) (*.img) + BLX -raster- (rwv): Magellan topo (.blx) (*.blx) + GeoRaster -raster- (rw+s): Oracle Spatial GeoRaster + PostGISRaster -raster- (rws): PostGIS Raster driver + SAGA -raster- (rw+v): SAGA GIS Binary Grid (.sdat, .sg-grd-z) (*.sdat, *.sg-grd-z) + XYZ -raster- (rwv): ASCII Gridded XYZ (*.xyz) + HF2 -raster- (rwv): HF2/HFZ heightfield raster (*.hf2) + OZI -raster- (rov): OziExplorer Image File + CTG -raster- (rov): USGS LULC Composite Theme Grid + ZMap -raster- (rwv): ZMap Plus Grid (*.dat) + NGSGEOID -raster- (rov): NOAA NGS Geoid Height Grids (*.bin) + IRIS -raster- (rov): IRIS data (.PPI, .CAPPi etc) (*.ppi) + PRF -raster- (rov): Racurs PHOTOMOD PRF (*.prf) + EEDAI -raster- (ros): Earth Engine Data API Image + DAAS -raster- (ro): Airbus DS Intelligence Data As A Service driver + SIGDEM -raster- (rwv): Scaled Integer Gridded DEM .sigdem (*.sigdem) + EXR -raster- (rw+vs): Extended Dynamic Range Image File Format (*.exr) + AVIF -raster- (rwvs): AV1 Image File Format (*.avif) + HEIF -raster- (rwv): ISO/IEC 23008-12:2017 High Efficiency Image File Format (*.heic) + TGA -raster- (rov): TGA/TARGA Image File Format (*.tga) + OGCAPI -raster,vector- (rov): OGCAPI + STACTA -raster- (rovs): Spatio-Temporal Asset Catalog Tiled Assets (*.json) + STACIT -raster- (rovs): Spatio-Temporal Asset Catalog Items + JPEGXL -raster- (rwv): JPEG-XL (*.jxl) + GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -raster,vector- (rw+v): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) + OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) + PLSCENES -raster,vector- (ro): Planet Labs Scenes API + NGW -raster,vector- (rw+s): NextGIS Web + GenBin -raster- (rov): Generic Binary (.hdr Labelled) + ENVI -raster- (rw+v): ENVI .hdr Labelled + EHdr -raster- (rw+v): ESRI .hdr Labelled (*.bil) + ISCE -raster- (rw+v): ISCE raster + Zarr -raster,multidimensional raster- (rw+vs): Zarr + RCM -raster- (rovs): Radarsat Constellation Mission XML Product + HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt b/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt new file mode 100644 index 000000000000..cd35f8279933 --- /dev/null +++ b/.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt @@ -0,0 +1,90 @@ +Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) + FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) + PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + netCDF -raster,multidimensional raster,vector- (rw+vs): Network Common Data Format (*.nc) + PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + VICAR -raster,vector- (rw+v): MIPL VICAR file + JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) + PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) + BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) + EEDA -vector- (ro): Earth Engine Data API + OGCAPI -raster,vector- (rov): OGCAPI + ESRI Shapefile -vector- (rw+v): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) + MapInfo File -vector- (rw+v): MapInfo File (*.tab, *.mif, *.mid) + UK .NTF -vector- (rov): UK .NTF + LVBAG -vector- (rov): Kadaster LV BAG Extract 2.0 (*.xml) + OGR_SDTS -vector- (rov): SDTS + S57 -vector- (rw+v): IHO S-57 (ENC) (*.000) + DGN -vector- (rw+v): Microstation DGN (*.dgn) + OGR_VRT -vector- (rov): VRT - Virtual Datasource (*.vrt) + Memory -vector- (rw+): Memory + CSV -vector- (rw+v): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) + NAS -vector- (rov): NAS - ALKIS (*.xml) + GML -vector- (rw+v): Geography Markup Language (GML) (*.gml, *.xml) + GPX -vector- (rw+v): GPX (*.gpx) + LIBKML -vector- (rw+v): Keyhole Markup Language (LIBKML) (*.kml, *.kmz) + KML -vector- (rw+v): Keyhole Markup Language (KML) (*.kml) + GeoJSON -vector- (rw+v): GeoJSON (*.json, *.geojson) + GeoJSONSeq -vector- (rw+v): GeoJSON Sequence (*.geojsonl, *.geojsons) + ESRIJSON -vector- (rov): ESRIJSON (*.json) + TopoJSON -vector- (rov): TopoJSON (*.json, *.topojson) + Interlis 1 -vector- (rw+v): Interlis 1 (*.itf, *.ili) + Interlis 2 -vector- (rw+v): Interlis 2 (*.xtf, *.xml, *.ili) + OGR_GMT -vector- (rw+v): GMT ASCII Vectors (.gmt) (*.gmt) + GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -raster,vector- (rw+v): SQLite / Spatialite / RasterLite2 (*.sqlite, *.db) + ODBC -vector- (ro): Open Database Connectivity (ODBC) (*.mdb, *.accdb) + WAsP -vector- (rw+v): WAsP .map format (*.map) + PGeo -vector- (ro): ESRI Personal GeoDatabase (*.mdb) + MSSQLSpatial -vector- (rw+): Microsoft SQL Server Spatial Database (BCP) + OGR_OGDI -vector- (ro): OGDI Vectors (VPF, VMAP, DCW) + PostgreSQL -vector- (rw+): PostgreSQL/PostGIS + MySQL -vector- (rw+): MySQL + OCI -vector- (rw+): Oracle Spatial + OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + FileGDB -vector- (rw+): ESRI FileGDB (*.gdb) + DXF -vector- (rw+v): AutoCAD DXF (*.dxf) + CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) + FlatGeobuf -vector- (rw+v): FlatGeobuf (*.fgb) + Geoconcept -vector- (rw+v): Geoconcept (*.gxt, *.txt) + GeoRSS -vector- (rw+v): GeoRSS + VFK -vector- (ro): Czech Cadastral Exchange Data Format (*.vfk) + PGDUMP -vector- (w+v): PostgreSQL SQL dump (*.sql) + OSM -vector- (rov): OpenStreetMap XML and PBF (*.osm, *.pbf) + GPSBabel -vector- (rw+): GPSBabel (*.mps, *.gdb, *.osm, *.tcx, *.igc) + OGR_PDS -vector- (rov): Planetary Data Systems TABLE + WFS -vector- (rov): OGC WFS (Web Feature Service) + OAPIF -vector- (ro): OGC API - Features + SOSI -vector- (ro): Norwegian SOSI Standard + EDIGEO -vector- (rov): French EDIGEO exchange format (*.thf) + SVG -vector- (rov): Scalable Vector Graphics (*.svg) + Idrisi -vector- (rov): Idrisi Vector (.vct) (*.vct) + XLS -vector- (ro): MS Excel format (*.xls) + ODS -vector- (rw+v): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) + XLSX -vector- (rw+v): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) + Elasticsearch -vector- (rw+): Elastic Search + Carto -vector- (rw+): Carto + AmigoCloud -vector- (rw+): AmigoCloud + SXF -vector- (rov): Storage and eXchange Format (*.sxf) + Selafin -vector- (rw+v): Selafin + JML -vector- (rw+v): OpenJUMP JML (*.jml) + PLSCENES -raster,vector- (ro): Planet Labs Scenes API + CSW -vector- (ro): OGC CSW (Catalog Service for the Web) + MongoDBv3 -vector- (ro): MongoDB (using libmongocxx v3 client) + VDV -vector- (rw+v): VDV-451/VDV-452/INTREST Data Format (*.txt, *.x10) + GMLAS -vector- (rwv): Geography Markup Language (GML) driven by application schemas (*.gml, *.xml) + MVT -vector- (rw+v): Mapbox Vector Tiles (*.mvt, *.mvt.gz, *.pbf) + NGW -raster,vector- (rw+s): NextGIS Web + MapML -vector- (rw+v): MapML + GTFS -vector- (rov): General Transit Feed Specification (*.zip) + PMTiles -vector- (rw+v): ProtoMap Tiles (*.pmtiles) + JSONFG -vector- (rw+v): OGC Features and Geometries JSON (*.json) + MiraMonVector -vector- (rw+v): MiraMon Vectors (.pol, .arc, .pnt) (*.pol, *.arc, *.pnt) + XODR -vector- (ro): OpenDRIVE - Open Dynamic Road Information for Vehicle Environment (*.xodr) + ADBC -vector- (ro): Arrow Database Connectivity + TIGER -vector- (rov): U.S. Census TIGER/Line + AVCBin -vector- (rov): Arc/Info Binary Coverage + AVCE00 -vector- (rov): Arc/Info E00 (ASCII) Coverage (*.e00) + AIVector -vector- (ro): Artificial Intelligence powered vector driver + HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.github/workflows/ubuntu_24.04/services.sh b/.github/workflows/ubuntu_24.04/services.sh index d4d9c002aa2c..19fe9c62404a 100755 --- a/.github/workflows/ubuntu_24.04/services.sh +++ b/.github/workflows/ubuntu_24.04/services.sh @@ -7,9 +7,9 @@ set -ex ################## # MSSQL: server side -docker rm -f gdal-sql1 -docker pull mcr.microsoft.com/mssql/server:2017-latest -docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=DummyPassw0rd' -p 1433:1433 --name gdal-sql1 -d mcr.microsoft.com/mssql/server:2017-latest +#docker rm -f gdal-sql1 +#docker pull mcr.microsoft.com/mssql/server:2017-latest +#docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=DummyPassw0rd' -p 1433:1433 --name gdal-sql1 -d mcr.microsoft.com/mssql/server:2017-latest # MySQL 8 docker rm -f gdal-mysql1 @@ -38,7 +38,7 @@ docker run --name gdal-mongo -p 27018:27017 -d mongo:4.4 sleep 10 # MSSQL -docker exec -t gdal-sql1 /opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -U SA -P DummyPassw0rd -Q "CREATE DATABASE TestDB" +#docker exec -t gdal-sql1 /opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -U SA -P DummyPassw0rd -Q "CREATE DATABASE TestDB" # MySQL docker exec gdal-mysql1 sh -c "echo 'CREATE DATABASE test; SELECT Version()' | mysql -uroot -ppasswd" diff --git a/.github/workflows/ubuntu_24.04/test.sh b/.github/workflows/ubuntu_24.04/test.sh index 5ce09486593d..9276321ef0c0 100755 --- a/.github/workflows/ubuntu_24.04/test.sh +++ b/.github/workflows/ubuntu_24.04/test.sh @@ -7,6 +7,13 @@ set -e LD_LIBRARY_PATH="/opt/instantclient_19_9:/opt/instantclient_19_9/lib:${LD_LIBRARY_PATH}" export LD_LIBRARY_PATH +# Check the build includes the expected drivers +gdalinfo --formats > found_formats.txt +ogrinfo --formats >> found_formats.txt +cat found_formats.txt +cat ../.github/workflows/ubuntu_24.04/expected_gdalinfo_formats.txt ../.github/workflows/ubuntu_24.04/expected_ogrinfo_formats.txt > expected_formats.txt +diff -u expected_formats.txt found_formats.txt + # Test development launcher script gdal_edit --version @@ -34,6 +41,6 @@ AZURE_STORAGE_CONNECTION_STRING=${AZURITE_STORAGE_CONNECTION_STRING} python3 -c # MongoDB v3 (cd autotest && MONGODBV3_TEST_PORT=27018 MONGODBV3_TEST_HOST=$IP $PYTEST ogr/ogr_mongodbv3.py) -(cd autotest && OGR_MSSQL_CONNECTION_STRING="MSSQL:server=$IP;database=TestDB;driver=ODBC Driver 17 for SQL Server;UID=SA;PWD=DummyPassw0rd" $PYTEST ogr/ogr_mssqlspatial.py) +# (cd autotest && OGR_MSSQL_CONNECTION_STRING="MSSQL:server=$IP;database=TestDB;driver=ODBC Driver 17 for SQL Server;UID=SA;PWD=DummyPassw0rd" $PYTEST ogr/ogr_mssqlspatial.py) (cd autotest && $PYTEST) diff --git a/.github/workflows/windows_build.yml b/.github/workflows/windows_build.yml index 8250039a9b14..91146477d8be 100644 --- a/.github/workflows/windows_build.yml +++ b/.github/workflows/windows_build.yml @@ -4,12 +4,14 @@ on: push: paths-ignore: - 'doc/**' + - 'docker/**' branches-ignore: - 'backport**' - 'dependabot**' pull_request: paths-ignore: - 'doc/**' + - 'docker/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -56,7 +58,7 @@ jobs: git config --global core.autocrlf false - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set environment shell: pwsh diff --git a/.github/workflows/windows_conda_expected_gdalinfo_formats.txt b/.github/workflows/windows_conda_expected_gdalinfo_formats.txt new file mode 100644 index 000000000000..f37c96eec515 --- /dev/null +++ b/.github/workflows/windows_conda_expected_gdalinfo_formats.txt @@ -0,0 +1,157 @@ +Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) + VRT -raster,multidimensional raster- (rw+v): Virtual Raster (*.vrt) + DERIVED -raster- (ro): Derived datasets using VRT pixel functions + GTI -raster- (rov): GDAL Raster Tile Index (*.gti.gpkg, *.gti.fgb, *.gti) + SNAP_TIFF -raster- (rov): Sentinel Application Processing GeoTIFF + GTiff -raster- (rw+vs): GeoTIFF (*.tif, *.tiff) + COG -raster- (wv): Cloud optimized GeoTIFF generator (*.tif, *.tiff) + NITF -raster- (rw+vs): National Imagery Transmission Format (*.ntf) + RPFTOC -raster- (rovs): Raster Product Format TOC format (*.toc) + ECRGTOC -raster- (rovs): ECRG TOC format (*.xml) + HFA -raster- (rw+v): Erdas Imagine Images (.img) (*.img) + SAR_CEOS -raster- (rov): CEOS SAR Image + CEOS -raster- (rov): CEOS Image + JAXAPALSAR -raster- (rov): JAXA PALSAR Product Reader (Level 1.1/1.5) + GFF -raster- (rov): Ground-based SAR Applications Testbed File Format (.gff) (*.gff) + ELAS -raster- (rw+v): ELAS + ESRIC -raster- (rov): Esri Compact Cache (*.json, *.tpkx) + AIG -raster- (rov): Arc/Info Binary Grid + AAIGrid -raster- (rwv): Arc/Info ASCII Grid (*.asc) + GRASSASCIIGrid -raster- (rov): GRASS ASCII Grid + ISG -raster- (rov): International Service for the Geoid (*.isg) + SDTS -raster- (rov): SDTS Raster (*.ddf) + DTED -raster- (rwv): DTED Elevation Raster (*.dt0, *.dt1, *.dt2) + PNG -raster- (rwv): Portable Network Graphics (*.png) + JPEG -raster- (rwv): JPEG JFIF (*.jpg, *.jpeg) + MEM -raster,multidimensional raster- (rw+): In Memory Raster + JDEM -raster- (rov): Japanese DEM (.mem) (*.mem) + GIF -raster- (rwv): Graphics Interchange Format (.gif) (*.gif) + BIGGIF -raster- (rov): Graphics Interchange Format (.gif) (*.gif) + ESAT -raster- (rov): Envisat Image Format (*.n1) + FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) + BSB -raster- (rov): Maptech BSB Nautical Charts (*.kap) + XPM -raster- (rwv): X11 PixMap Format (*.xpm) + BMP -raster- (rw+v): MS Windows Device Independent Bitmap (*.bmp) + DIMAP -raster- (rovs): SPOT DIMAP + AirSAR -raster- (rov): AirSAR Polarimetric Image + RS2 -raster- (rovs): RadarSat 2 XML Product + SAFE -raster- (rov): Sentinel-1 SAR SAFE Product + PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + PCRaster -raster- (rw+): PCRaster Raster File (*.map) + ILWIS -raster- (rw+v): ILWIS Raster Map (*.mpr, *.mpl) + SGI -raster- (rw+v): SGI Image File Format 1.0 (*.rgb) + SRTMHGT -raster- (rwv): SRTMHGT File Format (*.hgt) + Leveller -raster- (rw+v): Leveller heightfield (*.ter) + Terragen -raster- (rw+v): Terragen heightfield (*.ter) + netCDF -raster,multidimensional raster,vector- (rw+s): Network Common Data Format (*.nc) + HDF4 -raster,multidimensional raster- (ros): Hierarchical Data Format Release 4 (*.hdf) + HDF4Image -raster- (rw+): HDF4 Dataset + ISIS3 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 3) (*.lbl, *.cub) + ISIS2 -raster- (rw+v): USGS Astrogeology ISIS cube (Version 2) + PDS -raster- (rov): NASA Planetary Data System + PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + VICAR -raster,vector- (rw+v): MIPL VICAR file + TIL -raster- (rov): EarthWatch .TIL + ERS -raster- (rw+v): ERMapper .ers Labelled (*.ers) + JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) + L1B -raster- (rovs): NOAA Polar Orbiter Level 1b Data Set + FIT -raster- (rwv): FIT Image + GRIB -raster,multidimensional raster- (rwv): GRIdded Binary (.grb, .grb2) (*.grb, *.grb2, *.grib2) + RMF -raster- (rw+v): Raster Matrix Format (*.rsw) + WCS -raster- (rovs): OGC Web Coverage Service + WMS -raster- (rwvs): OGC Web Map Service + MSGN -raster- (rov): EUMETSAT Archive native (.nat) (*.nat) + MSG -raster- (ro): MSG HRIT Data + RST -raster- (rw+v): Idrisi Raster A.1 (*.rst) + GSAG -raster- (rwv): Golden Software ASCII Grid (.grd) (*.grd) + GSBG -raster- (rw+v): Golden Software Binary Grid (.grd) (*.grd) + GS7BG -raster- (rw+v): Golden Software 7 Binary Grid (.grd) (*.grd) + COSAR -raster- (rov): COSAR Annotated Binary Matrix (TerraSAR-X) + TSX -raster- (rov): TerraSAR-X Product + COASP -raster- (ro): DRDC COASP SAR Processor Raster (*.hdr) + R -raster- (rwv): R Object Data Store (*.rda) + MAP -raster- (rov): OziExplorer .MAP + KMLSUPEROVERLAY -raster- (rwv): Kml Super Overlay (*.kml, *.kmz) + WEBP -raster- (rwv): WEBP (*.webp) + PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + Rasterlite -raster- (rwvs): Rasterlite (*.sqlite) + MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) + PLMOSAIC -raster- (ro): Planet Labs Mosaics API + CALS -raster- (rwv): CALS (Type 1) (*.cal, *.ct1) + WMTS -raster- (rwv): OGC Web Map Tile Service + SENTINEL2 -raster- (rovs): Sentinel 2 + MRF -raster- (rw+v): Meta Raster Format (*.mrf) + TileDB -raster,multidimensional raster,vector- (rw+vs): TileDB + PNM -raster- (rw+v): Portable Pixmap Format (netpbm) (*.pgm, *.ppm, *.pnm) + DOQ1 -raster- (rov): USGS DOQ (Old Style) + DOQ2 -raster- (rov): USGS DOQ (New Style) + PAux -raster- (rw+v): PCI .aux Labelled + MFF -raster- (rw+v): Vexcel MFF Raster (*.hdr) + MFF2 -raster- (rw+): Vexcel MFF2 (HKV) Raster + GSC -raster- (rov): GSC Geogrid + FAST -raster- (rov): EOSAT FAST Format + BT -raster- (rw+v): VTP .bt (Binary Terrain) 1.3 Format (*.bt) + LAN -raster- (rw+v): Erdas .LAN/.GIS + CPG -raster- (rov): Convair PolGASP + NDF -raster- (rov): NLAPS Data Format + EIR -raster- (rov): Erdas Imagine Raw + DIPEx -raster- (rov): DIPEx + LCP -raster- (rwv): FARSITE v.4 Landscape File (.lcp) (*.lcp) + GTX -raster- (rw+v): NOAA Vertical Datum .GTX (*.gtx) + LOSLAS -raster- (rov): NADCON .los/.las Datum Grid Shift + NTv2 -raster- (rw+vs): NTv2 Datum Grid Shift (*.gsb, *.gvb) + CTable2 -raster- (rw+v): CTable2 Datum Grid Shift + ACE2 -raster- (rov): ACE2 (*.ACE2) + SNODAS -raster- (rov): Snow Data Assimilation System (*.hdr) + KRO -raster- (rw+v): KOLOR Raw (*.kro) + ROI_PAC -raster- (rw+v): ROI_PAC raster + RRASTER -raster- (rw+v): R Raster (*.grd) + BYN -raster- (rw+v): Natural Resources Canada's Geoid (*.byn, *.err) + NOAA_B -raster- (rov): NOAA GEOCON/NADCON5 .b format (*.b) + RIK -raster- (rov): Swedish Grid RIK (.rik) (*.rik) + USGSDEM -raster- (rwv): USGS Optional ASCII DEM (and CDED) (*.dem) + GXF -raster- (rov): GeoSoft Grid Exchange Format (*.gxf) + KEA -raster- (rw+v): KEA Image Format (.kea) (*.kea) + BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) + S102 -raster,multidimensional raster- (rovs): S-102 Bathymetric Surface Product (*.h5) + S104 -raster,multidimensional raster- (rov): S-104 Water Level Information for Surface Navigation Product (*.h5) + S111 -raster,multidimensional raster- (rov): Surface Currents Product (*.h5) + HDF5 -raster,multidimensional raster- (rovs): Hierarchical Data Format Release 5 (*.h5, *.hdf5) + HDF5Image -raster- (rov): HDF5 Dataset + NWT_GRD -raster- (rw+v): Northwood Numeric Grid Format .grd/.tab (*.grd) + NWT_GRC -raster- (rov): Northwood Classified Grid Format .grc/.tab (*.grc) + ADRG -raster- (rw+vs): ARC Digitized Raster Graphics (*.gen) + SRP -raster- (rovs): Standard Raster Product (ASRP/USRP) (*.img) + BLX -raster- (rwv): Magellan topo (.blx) (*.blx) + PostGISRaster -raster- (rws): PostGIS Raster driver + SAGA -raster- (rw+v): SAGA GIS Binary Grid (.sdat, .sg-grd-z) (*.sdat, *.sg-grd-z) + XYZ -raster- (rwv): ASCII Gridded XYZ (*.xyz) + HF2 -raster- (rwv): HF2/HFZ heightfield raster (*.hf2) + OZI -raster- (rov): OziExplorer Image File + CTG -raster- (rov): USGS LULC Composite Theme Grid + ZMap -raster- (rwv): ZMap Plus Grid (*.dat) + NGSGEOID -raster- (rov): NOAA NGS Geoid Height Grids (*.bin) + IRIS -raster- (rov): IRIS data (.PPI, .CAPPi etc) (*.ppi) + PRF -raster- (rov): Racurs PHOTOMOD PRF (*.prf) + EEDAI -raster- (ros): Earth Engine Data API Image + DAAS -raster- (ro): Airbus DS Intelligence Data As A Service driver + SIGDEM -raster- (rwv): Scaled Integer Gridded DEM .sigdem (*.sigdem) + AVIF -raster- (rwvs): AV1 Image File Format (*.avif) + HEIF -raster- (rwv): ISO/IEC 23008-12:2017 High Efficiency Image File Format (*.heic) + TGA -raster- (rov): TGA/TARGA Image File Format (*.tga) + OGCAPI -raster,vector- (rov): OGCAPI + STACTA -raster- (rovs): Spatio-Temporal Asset Catalog Tiled Assets (*.json) + STACIT -raster- (rovs): Spatio-Temporal Asset Catalog Items + NSIDCbin -raster- (rov): NSIDC Sea Ice Concentrations binary (.bin) (*.bin) + GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) + OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) + PLSCENES -raster,vector- (ro): Planet Labs Scenes API + NGW -raster,vector- (rw+s): NextGIS Web + GenBin -raster- (rov): Generic Binary (.hdr Labelled) + ENVI -raster- (rw+v): ENVI .hdr Labelled + EHdr -raster- (rw+v): ESRI .hdr Labelled (*.bil) + ISCE -raster- (rw+v): ISCE raster + Zarr -raster,multidimensional raster- (rw+vs): Zarr + RCM -raster- (rovs): Radarsat Constellation Mission XML Product + HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.github/workflows/windows_conda_expected_ogrinfo_formats.txt b/.github/workflows/windows_conda_expected_ogrinfo_formats.txt new file mode 100644 index 000000000000..c910b318a6cf --- /dev/null +++ b/.github/workflows/windows_conda_expected_ogrinfo_formats.txt @@ -0,0 +1,85 @@ +Supported Formats: (ro:read-only, rw:read-write, +:update, v:virtual-I/O s:subdatasets) + FITS -raster,vector- (rw+): Flexible Image Transport System (*.fits) + PCIDSK -raster,vector- (rw+v): PCIDSK Database File (*.pix) + netCDF -raster,multidimensional raster,vector- (rw+s): Network Common Data Format (*.nc) + PDS4 -raster,vector- (rw+vs): NASA Planetary Data System 4 (*.xml) + VICAR -raster,vector- (rw+v): MIPL VICAR file + JP2OpenJPEG -raster,vector- (rwv): JPEG-2000 driver based on JP2OpenJPEG library (*.jp2, *.j2k) + PDF -raster,vector- (rw+vs): Geospatial PDF (*.pdf) + MBTiles -raster,vector- (rw+v): MBTiles (*.mbtiles) + TileDB -raster,multidimensional raster,vector- (rw+vs): TileDB + BAG -raster,multidimensional raster,vector- (rw+v): Bathymetry Attributed Grid (*.bag) + EEDA -vector- (ro): Earth Engine Data API + OGCAPI -raster,vector- (rov): OGCAPI + ESRI Shapefile -vector- (rw+v): ESRI Shapefile (*.shp, *.dbf, *.shz, *.shp.zip) + MapInfo File -vector- (rw+v): MapInfo File (*.tab, *.mif, *.mid) + UK .NTF -vector- (rov): UK .NTF + LVBAG -vector- (rov): Kadaster LV BAG Extract 2.0 (*.xml) + OGR_SDTS -vector- (rov): SDTS + S57 -vector- (rw+v): IHO S-57 (ENC) (*.000) + DGN -vector- (rw+v): Microstation DGN (*.dgn) + OGR_VRT -vector- (rov): VRT - Virtual Datasource (*.vrt) + Memory -vector- (rw+): Memory + CSV -vector- (rw+v): Comma Separated Value (.csv) (*.csv, *.tsv, *.psv) + NAS -vector- (rov): NAS - ALKIS (*.xml) + GML -vector- (rw+v): Geography Markup Language (GML) (*.gml, *.xml) + GPX -vector- (rw+v): GPX (*.gpx) + KML -vector- (rw+v): Keyhole Markup Language (KML) (*.kml) + GeoJSON -vector- (rw+v): GeoJSON (*.json, *.geojson) + GeoJSONSeq -vector- (rw+v): GeoJSON Sequence (*.geojsonl, *.geojsons) + ESRIJSON -vector- (rov): ESRIJSON (*.json) + TopoJSON -vector- (rov): TopoJSON (*.json, *.topojson) + Interlis 1 -vector- (rw+v): Interlis 1 (*.itf, *.ili) + Interlis 2 -vector- (rw+v): Interlis 2 (*.xtf, *.xml, *.ili) + OGR_GMT -vector- (rw+v): GMT ASCII Vectors (.gmt) (*.gmt) + GPKG -raster,vector- (rw+vs): GeoPackage (*.gpkg, *.gpkg.zip) + SQLite -vector- (rw+v): SQLite / Spatialite (*.sqlite, *.db) + ODBC -vector- (ro): Open Database Connectivity (ODBC) (*.mdb, *.accdb) + WAsP -vector- (rw+v): WAsP .map format (*.map) + PGeo -vector- (ro): ESRI Personal GeoDatabase (*.mdb) + MSSQLSpatial -vector- (rw+): Microsoft SQL Server Spatial Database (BCP) + PostgreSQL -vector- (rw+): PostgreSQL/PostGIS + OpenFileGDB -raster,vector- (rw+v): ESRI FileGeodatabase (using OpenFileGDB) (*.gdb) + DXF -vector- (rw+v): AutoCAD DXF (*.dxf) + CAD -raster,vector- (rovs): AutoCAD Driver (*.dwg) + FlatGeobuf -vector- (rw+v): FlatGeobuf (*.fgb) + Geoconcept -vector- (rw+v): Geoconcept (*.gxt, *.txt) + GeoRSS -vector- (rw+v): GeoRSS + VFK -vector- (ro): Czech Cadastral Exchange Data Format (*.vfk) + PGDUMP -vector- (w+v): PostgreSQL SQL dump (*.sql) + OSM -vector- (rov): OpenStreetMap XML and PBF (*.osm, *.pbf) + GPSBabel -vector- (rw+): GPSBabel (*.mps, *.gdb, *.osm, *.tcx, *.igc) + OGR_PDS -vector- (rov): Planetary Data Systems TABLE + WFS -vector- (rov): OGC WFS (Web Feature Service) + OAPIF -vector- (ro): OGC API - Features + EDIGEO -vector- (rov): French EDIGEO exchange format (*.thf) + SVG -vector- (rov): Scalable Vector Graphics (*.svg) + Idrisi -vector- (rov): Idrisi Vector (.vct) (*.vct) + XLS -vector- (ro): MS Excel format (*.xls) + ODS -vector- (rw+v): Open Document/ LibreOffice / OpenOffice Spreadsheet (*.ods) + XLSX -vector- (rw+v): MS Office Open XML spreadsheet (*.xlsx, *.xlsm) + Elasticsearch -vector- (rw+): Elastic Search + Carto -vector- (rw+): Carto + AmigoCloud -vector- (rw+): AmigoCloud + SXF -vector- (rov): Storage and eXchange Format (*.sxf) + Selafin -vector- (rw+v): Selafin + JML -vector- (rw+v): OpenJUMP JML (*.jml) + PLSCENES -raster,vector- (ro): Planet Labs Scenes API + CSW -vector- (ro): OGC CSW (Catalog Service for the Web) + VDV -vector- (rw+v): VDV-451/VDV-452/INTREST Data Format (*.txt, *.x10) + GMLAS -vector- (rwv): Geography Markup Language (GML) driven by application schemas (*.gml, *.xml) + MVT -vector- (rw+v): Mapbox Vector Tiles (*.mvt, *.mvt.gz, *.pbf) + NGW -raster,vector- (rw+s): NextGIS Web + MapML -vector- (rw+v): MapML + Parquet -vector- (rw+v): (Geo)Parquet (*.parquet) + Arrow -vector- (rw+v): (Geo)Arrow IPC File Format / Stream (*.arrow, *.feather, *.arrows, *.ipc) + GTFS -vector- (rov): General Transit Feed Specification (*.zip) + PMTiles -vector- (rw+v): ProtoMap Tiles (*.pmtiles) + JSONFG -vector- (rw+v): OGC Features and Geometries JSON (*.json) + MiraMonVector -vector- (rw+v): MiraMon Vectors (.pol, .arc, .pnt) (*.pol, *.arc, *.pnt) + ADBC -vector- (ro): Arrow Database Connectivity + TIGER -vector- (rov): U.S. Census TIGER/Line + AVCBin -vector- (rov): Arc/Info Binary Coverage + AVCE00 -vector- (rov): Arc/Info E00 (ASCII) Coverage (*.e00) + AIVector -vector- (ro): Artificial Intelligence powered vector driver + HTTP -raster,vector- (ro): HTTP Fetching Wrapper diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7ea6c49bfc82..aeba53308bb2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,9 @@ repos: - id: black exclude: > (?x)^( - swig/python/osgeo/| + swig/python/osgeo/__init__.py| + swig/python/osgeo/gdalnumeric.py| + doc/source/_extensions/sphinxcontrib_programoutput_gdal.py| autotest/ogr/data/ ) - repo: https://github.com/timothycrosley/isort @@ -14,7 +16,9 @@ repos: - id: isort exclude: > (?x)^( - swig/python/osgeo/| + swig/python/osgeo/__init__.py| + swig/python/osgeo/gdalnumeric.py| + doc/source/_extensions/sphinxcontrib_programoutput_gdal.py| autotest/ogr/data/ ) - repo: https://github.com/pycqa/flake8 @@ -23,7 +27,9 @@ repos: - id: flake8 exclude: > (?x)^( - swig/python/osgeo/| + swig/python/osgeo/__init__.py| + swig/python/osgeo/gdalnumeric.py| + doc/source/_extensions/sphinxcontrib_programoutput_gdal.py| examples/| autotest/ogr/data/ ) @@ -36,7 +42,8 @@ repos: autotest/cpp/data/| autotest/gdrivers/data/| swig/| - third_party/| + third_party/fast_float/| + third_party/LercLib/| autotest/ogr/data/| alg/internal_libqhull/| apps/argparse/| @@ -52,12 +59,16 @@ repos: frmts/pcidsk/sdk| frmts/grib/degrib/degrib| frmts/grib/degrib/g2clib| + gcore/sse2neon.h| port/utf8.h| + ogr/ogrsf_frmts/adbc/ogr_adbc_internal.h| ogr/ogrsf_frmts/cad/libopencad/| ogr/ogrsf_frmts/geojson/libjson/| ogr/ogrsf_frmts/flatgeobuf/flatbuffers/| ogr/ogrsf_frmts/pmtiles/pmtiles/| + ogr/ogrsf_frmts/ods/ods_formula_parser.cpp| ogr/ogrsf_frmts/sqlite/sqlite_rtree_bulk_load| ogr/swq_parser.cpp| - ogr/swq_parser.hpp + ogr/swq_parser.hpp| + doc/source/ ) diff --git a/CITATION.cff b/CITATION.cff index a4b3a817404c..f55417d0e5bb 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,8 +2,8 @@ cff-version: 1.2.0 message: Please cite this software using these metadata or in the CITATION file. type: software title: GDAL -version: 3.8.3 -date-released: 2024-01-02 +version: 3.10.0 +date-released: 2024-11-01 doi: 10.5281/zenodo.5884351 abstract: GDAL is a translator library for raster and vector geospatial data formats that is released under an MIT style Open Source License by the Open diff --git a/CMakeLists.txt b/CMakeLists.txt index 367cda089dca..460537e2fcda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ include(cmake/helpers/GdalCMakeMinimumRequired.cmake) cmake_minimum_required(VERSION ${GDAL_CMAKE_VERSION_MIN}...${GDAL_CMAKE_VERSION_MAX}) project(gdal LANGUAGES C CXX) -include(CTest) set(GDAL_LIB_TARGET_NAME GDAL) @@ -95,6 +94,16 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86|AMD64)") endif () endif () +else() + + # Check ability to use Arm Neon optimizations + include(CheckCXXSourceCompiles) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/gcore") + check_cxx_source_compiles("#include \"include_sse2neon.h\"\nint main() { return 0; }" SSE2NEON_COMPILES) + cmake_pop_check_state() + endif () # option(CLANG_TIDY_ENABLED "Run clang-tidy with the compiler." OFF) @@ -224,6 +233,10 @@ endif() # include(${CMAKE_CURRENT_SOURCE_DIR}/gdal.cmake) +option(BUILD_TESTING "Build the testing tree." ON) +if (BUILD_TESTING) + enable_testing() +endif() if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/autotest") # unit tests add_subdirectory(autotest/cpp) diff --git a/Doxyfile b/Doxyfile index 4bf006b3802a..4a896612e813 100644 --- a/Doxyfile +++ b/Doxyfile @@ -388,8 +388,6 @@ INPUT = port \ ogr \ ogr/ogrsf_frmts \ ogr/ogrsf_frmts/generic \ - ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp \ - ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp \ swig/python/gdal-utils/scripts \ gnm \ doxygen_index.md @@ -417,7 +415,9 @@ RECURSIVE = NO # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = gcore/rawdataset.cpp \ - gcore/rawdataset.h + gcore/rawdataset.h \ + gcore/include_sse2neon.h \ + gcore/sse2neon.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded @@ -945,7 +945,8 @@ PREDEFINED = HAVE_DLFCN_H \ CPLSTRING_METHOD_DLL= \ CPL_NO_RETURN= \ EXPERIMENTAL_CPL_WARN_UNUSED_RESULT= \ - CPL_MULTIPROC_PTHREAD + CPL_MULTIPROC_PTHREAD \ + CPL_NON_FINAL= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE index afb1e184452f..81b1bc871d17 100644 --- a/HOWTO-RELEASE +++ b/HOWTO-RELEASE @@ -29,29 +29,29 @@ Prerequisites: Process : -1) "make completion" to regenerate scripts/gdal-bash-completion.sh - if new command line switches have been added. scripts/completionFinder.py - must also be edited before if new utilities/scripts are added/removed. +1) "make completion" to regenerate scripts/gdal-bash-completion.sh + if new command line switches have been added. scripts/completionFinder.py + must also be edited before if new utilities/scripts are added/removed. -2.1) Update the release date, and number information in gcore/gdal_version.h.in - (*NOT* gdal_version.h which is a generated file) - Note: the format of GDAL_RELEASE_DATE should be YYYYMMDD. +2) Update the release date, and number information in gcore/gdal_version.h.in + (*NOT* gdal_version.h which is a generated file) + Note: the format of GDAL_RELEASE_DATE should be YYYYMMDD. -2.2) Update two instances of year in CITATION file to the current year. +3) Update two instances of year in CITATION file to the current year. -2.3) Update "version" and "date-released" in CITATION.cff (Note: the DOI does - *not* need to be updated as it is a generic one) +4) Update "version" and "date-released" in CITATION.cff (Note: the DOI does + *not* need to be updated as it is a generic one) -3) Update the VERSION file (if not already done) +5) Update the VERSION file (if not already done) -3.1) Update the version information in the following files: - - ./swig/python/gdal-utils/osgeo_utils/__init__.py (gdal-utils python package) - - ./swig/python/README.rst (libgdal) +6) Update the version information in the following files: + - ./swig/python/gdal-utils/osgeo_utils/__init__.py (gdal-utils python package) + - ./swig/python/README.rst (libgdal) -4) Update the GDAL_SOVERSION number at top of gdal.cmake according to the +7) Update the GDAL_SOVERSION number at top of gdal.cmake according to the directions given in the comment preceding it. -5) Prepare release overview in the NEWS.md file. For example, to get all changes +8) Prepare release overview in the NEWS.md file. For example, to get all changes from v3.4.0 to current HEAD git log --reverse -v v3.4.0..HEAD . ":(exclude)autotest" ":(exclude)doc" ":(exclude).github" @@ -62,23 +62,28 @@ Process : - for bugfixes releases, forward port additions of NEWS.md to master -6) If this is a feature release (e.g 3.1), prepare a branch. +9) Update doc/source/about_no_title.rst, doc/source/download.rst and doc/source/download_past.rst + to advertise the new release and link to the release notes. Do that in a dedicated commit. + + (It is necessary to do that at that stage, so that the ReadTheDocs "stable" branch, based on the latest tag, proposes to download it) + +10) If this is a feature release (e.g 3.1), prepare a branch. git checkout master git pull origin master git checkout -b release/3.1 git push origin release/3.1 -7) Tag the release with a RC suffix: +11) Tag the release with a RC suffix: git checkout release/3.1 git pull origin release/3.1 git tag -a -m "Create tag v3.1.0RC1" v3.1.0RC1 git push origin v3.1.0RC1 -8) Prepare archives +12) Prepare archives -8.0) Ensure you have the following prerequisites (beyond normal build deps): +12.0) Ensure you have the following prerequisites (beyond normal build deps): If make is not GNU make, e.g., export MAKE=gmake @@ -97,7 +102,7 @@ Process : md5sum (GNU version) in path (not a POSIX requirement) -8.1) Create the source distributions using the mkgdaldist.sh script. +12.1) Create the source distributions using the mkgdaldist.sh script. The argument should be the version number (i.e. 1.4.2). As our process involves doing betas or RCs, use the -rc option so that the filenames include this information (after promotion to official release, filename renaming will have @@ -118,7 +123,7 @@ Process : a previous release (diff -Nur gdal-3.0.1 gdal-3.0.2). This is more easily doable for a bugfix release. -8.2) Create a snapshot of the documentation (only for feature releases) +12.2) Create a snapshot of the documentation (only for feature releases) 1. Refresh https://download.osgeo.org/gdal/for_doc/javadoc.zip @@ -128,7 +133,7 @@ Process : 3. ./build_doc_snapshot 310 This generates gdal310doc.zip -8.3) Publish the resulting files on download.osgeo.org, +12.3) Publish the resulting files on download.osgeo.org, in /osgeo/download/gdal/X.Y.Z (where X.Y.Z is the version number) with ~/.ssh/config containing: @@ -137,23 +142,28 @@ Process : ProxyCommand ssh rouault@download.osgeo.org -W $(sed -e "s/^osgeo7-//;s/$/.lxd/" <<< "%h"):%p -9) Announce the release candidate availability to gdal-dev@ - Example: https://lists.osgeo.org/pipermail/gdal-dev/2019-June/050509.html +13) Announce the release candidate availability to gdal-dev@ + Example: https://lists.osgeo.org/pipermail/gdal-dev/2019-June/050509.html -10) If new RC is needed, update gcore/gdal_version.h.in with the new date +14) If new RC is needed, update gcore/gdal_version.h.in with the new date and update NEWS,and go to 7) If no new RC is needed, after a few days, raise a motion to gdal-dev@ for approval -11) Once the vote has positively completed, +15) Once the vote has positively completed, + +15.0) For a new feature release, update the STABLE_BRANCH repository variable + + Go to https://github.com/OSGeo/GDAL/settings/variables/actions/STABLE_BRANCH + and update the value to be release/x.y -11.1) Tag the release as final: +15.1) Tag the release as final: git checkout v3.1.0RC1 git tag -a -m "Create tag v3.1.0" v3.1.0 git push origin v3.1.0 -11.2) Log on download.osgeo.org, go to /osgeo/download/gdal/X.Y.Z +15.2) Log on download.osgeo.org, go to /osgeo/download/gdal/X.Y.Z Remove the RC suffixes for the final RC, like: mv gdal-3.8.3rc1.tar.xz gdal-3.8.3.tar.xz @@ -176,22 +186,18 @@ Process : Check that everything is fine: md5sum -c *.md5 -11.3) In /osgeo/download/gdal, add a symlink from X.Y.Z to CURRENT (except for stable releases in a "old" branch). +15.3) In /osgeo/download/gdal, add a symlink from X.Y.Z to CURRENT (except for stable releases in a "old" branch). % ln -sf X.Y.Z CURRENT -12) (Removed) - -13) Update doc/source/about_no_title.rst and doc/source/download.rst to advertise the new release and link to the release notes - -14) Update GitHub to close the release milestone. +16) Update GitHub to close the release milestone. Then create a new milestone for the next release. -15) Upload the new Python bindings to Pypi (requires upload rights to +17) Upload the new Python bindings to Pypi (requires upload rights to the GDAL package by one of the current owners : HowardB/FrankW/EvenR) ( procedure taken from http://peterdowns.com/posts/first-time-with-pypi.html ) -15.1) Prerequisite: +17.1) Prerequisite: a) Install twine https://pypi.org/project/twine/ b) Create a $HOME/.pypirc file : @@ -210,7 +216,7 @@ the GDAL package by one of the current owners : HowardB/FrankW/EvenR) username: yourlogin password: yourpassword -15.2) create gdal sdist and upload to pypi: +17.2) create gdal sdist and upload to pypi: a) Create a build directory if not already done. Go to it and run cmake @@ -227,7 +233,7 @@ the GDAL package by one of the current owners : HowardB/FrankW/EvenR) f) For real : twine upload dist/gdal-*.gz -15.3) create gdal-utils wheel and upload to pypi: +17.3) create gdal-utils wheel and upload to pypi: a) cd $BUILD_DIR/swig/python/gdal-utils @@ -242,7 +248,7 @@ the GDAL package by one of the current owners : HowardB/FrankW/EvenR) d) For real : twine upload dist/gdal_utils-*.whl -16) Generate signed maven artifacts with GPG for Java bindings. +18) Generate signed maven artifacts with GPG for Java bindings. This step is required in order to deploy the maven artifacts to the central Maven repository. Before this step can proceed you must set up a signing key as described here: @@ -272,7 +278,7 @@ the GDAL package by one of the current owners : HowardB/FrankW/EvenR) that contains all the maven artifacts with signatures. This file is what will be uploaded to maven central. See the next step. -17) Deploy maven artifacts to Maven central. +19) Deploy maven artifacts to Maven central. NOTE: Before you can deploy to maven central you must set up an account in Sonatype JIRA. That can be done here: @@ -329,14 +335,14 @@ e) Click the "Release" button and that is it! The release should be available in - gdalXYZ.zip.md5 - gdalautotest-X.Y.Z.zip -19) Regenerate Docker images +20) Regenerate Docker images e.g ./docker/build-all.sh --with-multi-arch --release --tag 3.3.1 --gdal v3.3.1 --proj 8.1.0 --platform linux/arm64,linux/amd64 --push and update docker/README.md with the latest release -20) Announce release to : +21) Announce release to : - major release: gdal-dev@lists.osgeo.org, gdal-announce@lists.osgeo.org, news_item@osgeo.org. - bugfix release: gdal-dev@lists.osgeo.org, gdal-announce@lists.osgeo.org @@ -348,10 +354,19 @@ Note: gdal-announce@ is moderated. Make sure that your email address is approved ('mod' tick disabled in https://lists.osgeo.org/mailman/admin/gdal-announce/members), or your message manually approved, with an administrator of the list. -21) For a feature release: after it has been done, in the master branch, update +22) For a feature release: after it has been done, in the master branch, update the VERSION to the next one and in gcore/gdal_version.h.in, update GDAL_VERSION_MAJOR/_MINOR, GDAL_RELEASE_NAME (with a dev suffix, like "3.7.0dev"), and set GDAL_RELEASE_DATE to a date like {YEAR}9999. Update swig/python/gdal-utils/osgeo_utils/__init__.py to something like (3, 6, 99, 0) if master is 3.7.0dev +23) For bugfixes releases, forward port to master changes done in + doc/source/about_no_title.rst, doc/source/download.rst and doc/source/download_past.rst + +24) For a feature release, enable a new version in the ReadTheDocs administration panel. + a) Go to https://readthedocs.org/projects/gdal/versions/ + b) In the "Activate a version" tab, enter "release/X.Y" in the text entry and click on the Filter button + c) Click on the Activate button + d) Go to https://readthedocs.org/projects/gdal/, and in the "Compile a version" drop-down list, + select the newt "release-X.Y" label and click on the "Compile a version" button diff --git a/MIGRATION_GUIDE.TXT b/MIGRATION_GUIDE.TXT index f1155642d493..6cc284dd316b 100644 --- a/MIGRATION_GUIDE.TXT +++ b/MIGRATION_GUIDE.TXT @@ -1,6 +1,29 @@ MIGRATION GUIDE FROM GDAL 3.9 to GDAL 3.10 ------------------------------------------ +- The OGR SQL parser has been modified to evaluate NULL values in boolean + operations similarly to other SQL engines (SQLite, PostgreSQL, etc.). Previously, + with a foo=NULL field, expressions ``foo NOT IN ('bar')`` and ``foo NOT LIKE ('bar')`` + would evaluate as true. Now the result is false (with the NULL state being + propagated to it). Concretely, to get the same results as in previous versions, + the above expressions must be rewritten as ``foo IS NULL OR foo NOT IN ('bar')`` + and ``foo IS NULL OR foo NOT LIKE ('bar')``. + +- MEM driver: opening a dataset with the MEM::: syntax is now disabled by + default because of security implications. This can be enabled by setting the + GDAL_MEM_ENABLE_OPEN build or configuration option. Creation of a 0-band MEM + dataset, and using the GDALDataset::AddBand() method with the DATAPOINTER, + PIXELOFFSET and LINEOFFSET options is the recommended way. For example, like + in https://github.com/OSGeo/gdal/blob/e32a2fde41a555b7948cece9ab9b4e979138e7dd/gcore/rasterio.cpp#L1534-L1576 + +- The Erdas Imagine (HFA) and Derived drivers are now optional drivers. Users + building with GDAL_BUILD_OPTIONAL_DRIVERS=OFF may need to explicitly enable + them with GDAL_ENABLE_DRIVER_HFA=ON and GDAL_ENABLE_DRIVER_DERIVED=ON. + The MapInfo, OGR_VRT and KML drivers are now an optional driver. Users + building with OGR_BUILD_OPTIONAL_DRIVERS=OFF may need to explicitly enable + them with OGR_ENABLE_DRIVER_TAB=ON, OGR_ENABLE_DRIVER_VRT=ON and + OGR_ENABLE_DRIVER_KML=ON. + - User code using VSIFEofL() to potentially to end read loops should also test the return code of the new VSIFError() function. Some virtual file systems that used to report errors through VSIFEofL() now do through VSIFError(). @@ -18,6 +41,9 @@ MIGRATION GUIDE FROM GDAL 3.9 to GDAL 3.10 - Python bindings: Band.GetStatistics() and Band.ComputeStatistics() now return a None value in case of error (when exceptions are not enabled) +- New color interpretation (GCI_xxxx) items have been added to the GDALColorInterp + enumeration. Code testing color interpretation may need to be adapted. + MIGRATION GUIDE FROM GDAL 3.8 to GDAL 3.9 ----------------------------------------- @@ -212,7 +238,7 @@ MIGRATION GUIDE FROM GDAL 2.4 to GDAL 3.0 - Unix build: Arguments of --with-pg changed to yes/no only. - Substantial changes, sometimes backward incompatible, in coordinate reference system and coordinate transformations have been introduced per - https://trac.osgeo.org/gdal/wiki/rfc73_proj6_wkt2_srsbarn + https://gdal.org/en/latest/development/rfc/rfc73_proj6_wkt2_srsbarn.html * OSRImportFromEPSG() takes into account official axis order. Traditional GIS-friendly axis order can be restored with OGRSpatialReference::SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); @@ -284,7 +310,7 @@ MIGRATION GUIDE FROM GDAL 2.2 to GDAL 2.3 1) RFC 70: Guessing output format from output file name extension for utilities -Link: https://trac.osgeo.org/gdal/wiki/rfc70_output_format_guess +Link: https://gdal.org/en/latest/development/rfc/rfc70_output_format_guess.html Before GDAL 2.3, if not specifying the output format to utilities, GeoTIFF or Shapefile were assumed for most utilities. Now, the output format will be @@ -294,7 +320,7 @@ not specified (but warnings were already emitted in such situations). 2) RFC 68: C++11 Compilation requirement -Link: https://trac.osgeo.org/gdal/wiki/rfc68_cplusplus11 +Link: https://gdal.org/en/latest/development/rfc/rfc68_cplusplus11.html GDAL now requires a C++11 compatible compiler. External code using GDAL C++ API will also need to enable at least C++11 compilation mode, if the compiler @@ -338,7 +364,7 @@ MIGRATION GUIDE FROM GDAL 2.1 to GDAL 2.2 A) RFC 64: Triangle, Polyhedral surface and TIN -Link: https://trac.osgeo.org/gdal/wiki/rfc64_triangle_polyhedralsurface_tin +Link: https://gdal.org/en/latest/development/rfc/rfc64_triangle_polyhedralsurface_tin.html Vector drivers can now return geometries of type wkbPolyhedralSurface, wkbTIN and wkbTriangle; and their Z, M and ZM variants (as well as for the type of @@ -347,7 +373,7 @@ writing geometries, must be ready to deal with them. B) RFC 67: Null values in OGR -Link: https://trac.osgeo.org/gdal/wiki/rfc67_nullfieldvalues +Link: https://gdal.org/en/latest/development/rfc/rfc67_nullfieldvalues.html Previously, the "unset" state of a field was used both for a unset state (ie no information for the field of the feature) or the NULL state of the @@ -372,7 +398,7 @@ MIGRATION GUIDE FROM GDAL 2.0 to GDAL 2.1 A) RFC 61: Support for measured geometries -Link: https://trac.osgeo.org/gdal/wiki/rfc61_support_for_measured_geometries +Link: https://gdal.org/en/latest/development/rfc/rfc61_support_for_measured_geometries.html The OGRwkbGeometryType enumeration has been extended with new values for the M and ZM variants of the geometry types. Client code may have to be upgraded @@ -394,7 +420,7 @@ Changes to the Perl bindings API are listed in swig/perl/Changes-in-the-API-in-2 A) RFC 46: Unification of GDAL and OGR driver models -Link: http://trac.osgeo.org/gdal/wiki/rfc46_gdal_ogr_unification +Link: https://gdal.org/en/latest/development/rfc/rfc46_gdal_ogr_unification.html C++ API: @@ -438,7 +464,7 @@ Behavior changes : B) RFC 49: Curve geometries -Link: http://trac.osgeo.org/gdal/wiki/rfc49_curve_geometries +Link: https://gdal.org/en/latest/development/rfc/rfc49_curve_geometries.html C/C++ API : @@ -459,7 +485,7 @@ Out-of-tree drivers : C) RFC 51: RasterIO() improvements : resampling and progress callback -Link: http://trac.osgeo.org/gdal/wiki/rfc51_rasterio_resampling_progress +Link: https://gdal.org/en/latest/development/rfc/rfc51_rasterio_resampling_progress.html Out-of-tree drivers : @@ -470,7 +496,7 @@ Out-of-tree drivers : D) RFC 31: OGR 64bit Integer Fields and FIDs -Link:http://trac.osgeo.org/gdal/wiki/rfc31_ogr_64 +Link: https://gdal.org/en/latest/development/rfc/rfc31_ogr_64.html C++ API: * OGRLayer::GetFeature(), OGRLayer::DeleteFeature(), OGRLayer::SetNextByIndex() take a GIntBig instead of a long @@ -491,7 +517,7 @@ Out-of-tree drivers : E) RFC 52: Strict OGR SQL quoting -Link: http://trac.osgeo.org/gdal/wiki/rfc52_strict_sql_quoting +Link: https://gdal.org/en/latest/development/rfc/rfc52_strict_sql_quoting.html No API changes @@ -506,7 +532,7 @@ Behavior changes: F) RFC 53: OGR not-null constraints and default values -Link: http://trac.osgeo.org/gdal/wiki/rfc53_ogr_notnull_default +Link: https://gdal.org/en/latest/development/rfc/rfc53_ogr_notnull_default.html API changes: * OGRFieldDefn::SetDefault() now takes a const char* as argument. @@ -515,7 +541,7 @@ API changes: G) RFC 54: Dataset transactions -Link: http://trac.osgeo.org/gdal/wiki/rfc54_dataset_transactions +Link: https://gdal.org/en/latest/development/rfc/rfc54_dataset_transactions.html Only API additions. @@ -531,7 +557,7 @@ Behavior changes: H) RFC 55: Refined SetFeature() and DeleteFeature() semantics -Link: http://trac.osgeo.org/gdal/wiki/rfc55_refined_setfeature_deletefeature_semantics +Link: https://gdal.org/en/latest/development/rfc/rfc55_refined_setfeature_deletefeature_semantics.html Behavior changes: * Drivers will now return OGRERR_NON_EXISTING_FEATURE when calling SetFeature() @@ -539,7 +565,7 @@ Behavior changes: I) RFC 56: -Link: https://trac.osgeo.org/gdal/wiki/rfc56_millisecond_precision +Link: https://gdal.org/en/latest/development/rfc/rfc56_millisecond_precision.html API/ABI changes: @@ -582,7 +608,7 @@ Behavior changes: J) RFC 57: 64-bit bucket count for histograms -Link: https://trac.osgeo.org/gdal/wiki/rfc57_histogram_64bit_count +Link: https://gdal.org/en/latest/development/rfc/rfc57_histogram_64bit_count.html C++ API: * GDALRasterBand::GetHistogram() and GDALRasterBand::SetDefaultHistogram() take a GUIntBig* instead of a int* for bucket counts. @@ -605,7 +631,7 @@ This file documents backwards incompatible changes. C++ API: * GDALRasterAttributeTable is now an abstract class. - See http://trac.osgeo.org/gdal/wiki/rfc40_enhanced_rat_support + See https://gdal.org/en/latest/development/rfc/rfc40_enhanced_rat_support.html The functionality of GDAL 1.X GDALRasterAttributeTable is now in GDALDefaultRasterAttributeTable. @@ -624,4 +650,4 @@ Changes that should likely not impact anybody : * OGRGeometryFactory::getGEOSGeometryFactory() has been removed. This method returned NULL since 2006 - ( http://trac.osgeo.org/gdal/changeset/9899/trunk/ogr/ogrgeometryfactory.cpp ) + ( https://github.com/OSGeo/gdal/commit/42d5fd976795b9c85aac2c4ffac12025e21697c1#diff-9b267dec2a69d6f56247a5525195973890780ce50ae8c9c809bf4818754f4e46L885 ) diff --git a/NEWS.md b/NEWS.md index 89236bf03253..a5317b1571b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,812 @@ +# GDAL/OGR 3.10.0 Release Notes + +GDAL/OGR 3.10.0 is a feature release. +Those notes include changes since GDAL 3.9.0, but not already included in a +GDAL 3.9.x bugfix release. + +## In a nutshell... + +* [RFC 101](https://gdal.org/en/latest/development/rfc/rfc101_raster_dataset_threadsafety.html): + Raster dataset read-only thread-safety +* New read/write [AVIF](https://gdal.org/en/latest/drivers/raster/avif.html) + raster driver +* New read-only [SNAP_TIFF](https://gdal.org/en/latest/drivers/raster/snap_tiff.html) + raster driver for Sentinel Application Processing GeoTIFF files +* New OGR read-only [XODR](https://gdal.org/en/latest/drivers/vector/xodr.html) + driver for OpenDRIVE (#9504) +* Code linting and security fixes +* Bump of shared lib major version + +## New optional dependencies + +* [libavif](https://github.com/AOMediaCodec/libavif) for AVIF driver +* [libopendrive](https://github.com/DLR-TS/libOpenDRIVE) for XODR driver + +## Backward compatibility issues + +See [MIGRATION_GUIDE.TXT](https://github.com/OSGeo/gdal/blob/release/3.10/MIGRATION_GUIDE.TXT) + +## Build + +* add html, man, latexpdf, doxygen, doxygen_check_warnings, clean_doc targets + (require doc/ subdirectory to be re-added) (#5484) +* Java and CSharp bindings: do not build sample/tests programs if + BUILD_TESTING=OFF (#9857) +* Allow following drivers to be built in new -DSTANDALONE=ON mode: MrSID, + JP2KAK, OCI, Arrow, Parquet, JP2OPENJPEG, TileDB, ECW, GeoRaster +* Internal zlib: update to 1.3.1 +* Internal libpng: update to 1.6.43 +* Add scripts/check_binaries.py to detect unknown binaries and run it in CI + +## General changes + +* Reduce excessive precision %.18g to %.17g +* Replace MIT license long text with 'SPDX-License-Identifier: MIT' (#10903) + +## GDAL 3.10.0 + +### Port + +* Add VSIMemGenerateHiddenFilename() and use it extensively in whole code base +* Add VSICopyFileRestartable() to allow restart of upload of large files +* Add VSIMultipartUploadXXXXX() functions for multi-part upload +* VSICopyFile(): detect error when reading source file, and delete output file + on error +* VSI CopyFile() implementations: make them actually robust to pszSource==nullptr +* VSIMallocAligned(): make behavior more predictable when nSize == 0 +* CPLHTTPFetch(): add a RETRY_CODES option (GDAL_HTTP_RETRY_CODES config option) + (#9441) +* /vsicurl/: honor 'Cache-Control: no-cache' header +* /vsicurl/: no longer forward Authorization header when doing redirection to + other hosts. +* /vsiaz/: add BLOB_TYPE=BLOCK and CHUNK_SIZE options to VSIFOpenEx2L() +* /vsis3/: avoid emitting a CPLError() when bSetError=false and access=r+b +* /vsigs/: make sure access token with GOOGLE_APPLICATION_FILE in authorized_user + mode is cached +* /vsimem/: make Read() error for a file not opened with read permissions +* /vsimem/: more efficient SetLength() +* /vsicrypt/: if opening in write-only mode, do so on the underlying file as well +* /vsigzip/: sanitize Eof() detection +* /vsigzip/: Read(): detect attempts to read more than 4 GB at once +* Add VSIFErrorL() and VSIFClearErrL(), and implement them in file systems +* VSIVirtualHandle: add a Interrupt() method and implement in in /vsicurl/ (and + related filesystems) +* VSIWin32Handle: Read(): handle cleanly nSize * nCount > UINT32_MAX +* Add VSIToCPLErrorWithMsg() +* CPLHTTPFetch(): Add support for GDAL_HTTP_VERSION=2PRIOR_KNOWLEDGE +* Add a cpl::contains(container, value) helper +* CPLFormFilename()/CPLGetDirname()/CPLGetPath(): make it work with + 'vsicurl/http://example.com?foo' type of filename, to fix Zarr driver +* Thread pool: Use std::function as pool job and job queue function (#10505, #10628) +* CPLHTTPGetOptionsFromEnv(): fallback to non-streaming filename with no path + specific option has been found on the streaming one +* CPLSpawn() (unix): correctly return the exit() code of the process +* CPLRecode(): make ISO-8859-2 and -15 and CP437/CP1250/CP1251/CP1252 to UTF-8 + always available + +### Core + +* Add new GCI_ constants in particular for infra-red and SAR, and standardize + a band-level IMAGERY metadata domain with "CENTRAL_WAVELENGTH_UM" and "FWHM_UM" +* Add GDALRasterBand::InterpolateAtPoint() and GDALRasterInterpolateAtPoint() +* GDALRasterBand: add convenience ReadRaster() methods accepting std::vector<> +* GDALIdentifyDriverEx(): pass nIdentifyFlags to GDALOpenInfo, so that drivers + can see which type of dataset is asked for +* GDALIdentifyDriverEx(): transmit papszAllowedDrivers to Identify() +* Deprecate GDALDestroyDriverManager() and OGRCleanupAll() +* GDALNoDataMaskBand::IRasterIO(): speed optimization +* Fix GDALDataTypeUnion() to check that the provided value fits into eDT +* Add GDALIsValueExactAs() +* GDALFindDataTypeForValue(): fix for integer values that can't be represented + as UInt64 +* GDALDataset::RasterIO() / GDALDatasetRasterIO[Ex](): accept a const int* + panBandList, instead of a int* +* Make GDALDataset::IRasterIO() implementations ready to switch to use + const int* panBandList (enabled only if -DDGDAL_BANDMAP_TYPE_CONST_SAFE) +* Add GDALOpenInfo::IsSingleAllowedDriver() +* GDALDriver::QuietDeleteForCreateCopy(): do not set error state when attempting + to open datasets +* Rasterband methods (histogram, statistics): make them compatible of a dataset + with more than 2 billion blocks +* gdal_priv_templates.hpp: implement GDALIsValueInRange<[u]int64_t]>, and add GDALIsValueExactAs<> +* GDALMDArray::GetResampled(): take into account good_wavelengths array for EMIT + dataset orthorectification +* EXIF reader: strip trailing space/nul character in ASCII tags +* GDALDatasetCopyWholeRaster(): fix SKIP_HOLES=YES in the interleaved case that + failed to detect holes +* GDALDriver::DefaultCreateCopy(): recognize SKIP_HOLES=YES option and forward + it to GDALDatasetCopyWholeRaster() +* Multidimensional API: add GDALMDArray::GetMeshGrid() +* Multidim: AsClassicDataset(): make it able to retrieve dataset metadata from PAM +* JSON TileMatrixSet parser: accept crs.uri and crs.wkt encodings (#10989) + +### Algorithms + +* Polygonize: optimizations to reduce runtime +* Polygonize: make it catch out of memory situations +* GDALRasterizeGeometries(): various robustness fixes +* GDALPansharpenOperation::PansharpenResampleJobThreadFunc(): make it more robust +* Contour: include minimum raster value as contour line when it exactly matches + the first level (#10167) +* GDALWarpResolveWorkingDataType(): ignore srcNoDataValue if it doesn't fit into + the data type of the source band +* Warper: fix shifted/aliased result with Lanczos resampling when XSCALE < 1 or + YSCALE < 1 (#11042) +* Warper: optimize speed of Lanczos resampling in Byte case without any + masking/alpha +* Warper: make sure to check that angular unit is degree for heuristics related + to geographic CRS (#10975) + +### Utilities + +* gdalinfo: add -nonodata and -nomask options +* gdalinfo/ogrinfo: make --formats -json work (#10878) +* gdalbuildvrt: add a -co switch (#11062) +* gdal_translate: use GDALIsValueExactAs<> to check range of [u]int64 nodata +* gdal_viewshed: multi-threaded optimization (#9991) +* gdal_viewshed: support observers to left, right, above and below of input + raster (#10264, #10352) +* gdal_viewshed: address potential issues with line-based interpolation (#10237) +* gdal_viewshed: add support for cumulative viewshed (#10674) +* gdal_contour: allow to use -fl with -i and -e (#10172) +* gdal_contour: add a -gt option to define the transaction flush interval + (default it to 100,000) (#10729) +* gdallocationinfo: add -r resampling switch +* gdalwarp: allow specifying units of warp memory (#10976) +* Use GDALArgumentParser for gdal_contour, gdallocationinfo, gdaltindex, + ogrtindex, gdal_footprint, gdal_create, gdalmdiminfo, gdalmdimtranslate, + gdaldem, gdalmanage, ogrlineref, gdal_rasterize +* GDALArgumentParser: support sub-parser +* --formats option: detail abbreviation codes +* crs2crs2grid.py: Update to work with current data output format from HTDP (#2655) + +### Raster drivers + +Multi-driver changes: + * BAG, GTI, HDF5, OGCAPI, netCDF, S102/S104/S111, STACTA, STACIT, TileDB, + VICAR, WMS, WMTS, XYZ: + relax identification checks when papszAllowedDrivers[] contains only the + driver name + +Derived driver: + * make it optional + +DIMAP driver: + * for PNEO products, use the new color interpretations for the NIR, RedEdge + and DeepBlue/Coastal bands + +DTED driver: + * added metadata items Security Control and Security Handling (#10173) + +EEDA/EEDAI drivers: + * add a VSI_PATH_FOR_AUTH open option to allow using a /vsigs/ path-specific + GOOGLE_APPLICATION_CREDENTIALS option + +GeoPackage driver: + * Implement ALTER TABLE RENAME for rasters (#10201) + * use GDALIsValueInRange<> to avoid potential undefined behavior casts + * in CreateCopy() without resampling, use IGetDataCoverageStatus() on the source + dataset + * detect non-RGBA tiles fully at 0 and do not write them + * implement IGetDataCoverageStatus() + +GRIB driver: + * display hint to speed-up operations when using gdalinfo on a remote GRIB2 + file with an .idx side car file + +GTI driver: + * multi-threaded IRasterIO() for non-overlapping tiles + * recognize STAC GeoParquet catalogs + * implement GetDataCoverageStatus() + * emit warning if bounding box from the tile's feature extent in the index does + not match actual bounding box of tile + +GTiff driver: + * fix nMaxBits computation for Float32/Float64 + * DiscardLsb(): use GDALIsValueExactAs<> to check range of nodata + * handle TIFF color map that uses a 256 multiplication factor and add open + option COLOR_TABLE_MULTIPLIER + * clearer error when attempting to create external JPEG compressed overviews on + dataset with color table + * honor GDAL_DISABLE_READDIR_ON_OPEN when working on a dataset opened with + OVERVIEW_LEVEL open option + * better error messages when trying to create too-large untiled JPEG/WEBP + compressed files (or with huge tiles) + * when reading a unrecognized value of color interpretation in the GDAL_METADATA, + expose it in a COLOR_INTERPRETATION metadata item + * use main dataset GetSiblingFiles() for overviews + * SRS writer: do not use EPSG:4326 if angular unit is not degree + * make driver optional (but must be explicitly disabled) + * tif_jxl: writer: propagate DISTANCE/QUALITY setting to extra channel + * fix memory leak when trying to open COG in update mode + * Internal libtiff: resync with upstream + +HEIF driver: + * correctly initialize PAM for multiple images per file + * make simple identification more robust (#10618) + * make it possibly accept AVIF files (depends on libheif capabilities) + +HFA driver: + * SRS reading: strip TOWGS84 when datum name is known, and use FindBestMatch() + to try to find known SRS (#10129) + * make driver optional and buildable as a plugin + +HTTP driver: + * make parsing of Content-Disposition header aware of double quotes around + filename= + +ISIS3 driver: + * Create(): open file(s) in wb+ mode if possible + +ISG driver: + * Parse dms in ISG format + +JP2ECW driver: + * report JPEG2000 tile size as GDAL block size for ECW SDK >= 5.1 + (up to 2048x2048 and dataset dimensions) + +JP2KAK driver: + * add Cycc=yes/no creation option to set YCbCr/YUV color space and set it to + YES by default (#10623) + +JP2Lura driver: + * fix Identify() method + * planned for removal in GDAL 3.11 + +JPEG driver: + * make sure not to expose DNG_UniqueCameraModel/DNG_CameraSerialNumber if the + corresponding EXIF tags are set at the same value + * add support for reading Pix4DMapper CRS from XMP + +JPEGXL driver: + * writer: propagate DISTANCE/QUALITY setting to extra channel (#11095) + * writer: allow a minimum DISTANCE of 0.01, max of 25 and revise QUALITY to + DISTANCE formula (#11095) + +KMLSuperOverlay driver: + * recognize with forming a rectangle (#10629) + +MEM driver: + * disable opening a dataset with MEM::: syntax by default (unless + GDAL_MEM_ENABLE_OPEN build or config option is set) + +MRF driver: + * (~twice) faster LERC V1 encoding (#10188) + * Add 64bit int support (#10265) + * Allow open of MRF-in-TAR as MRF (#10331) + * MRF/LERC: check that values are within target type range before casting + * enable QB3_FTL mode when available (#10753) + +netCDF driver: + * multidim: add OpenMDArray() options to set up nc_set_var_chunk_cache() + * use GDALIsValueExactAs<> to check range of [u]int64 nodata + * do not override GDALPamDataset::TrySaveXML() to allow proper mixing of + classic and multidim PAM metadata + * make sure CreateMetadataFromOtherVars() doesn't set PAM dirty flag + * simplify identification logic by just checking runtime availability of + HDF4/HDF5 drivers. + * CreateCopy(): fix taking into account NETCDF_DIM_EXTRA when source dataset is + not georeferenced + * do not emit error when longitude axis unit is degrees_east and latitude axis + unit is degrees_north (#11009) + +NITF driver: + * Create()/CreateCopy(): make sure that provided ABPP creation option is zero + left-padded + * add an alias of existing ABPP creation option as NBITS; propagate NBITS/ABPP + creation option to JPEG2000 drivers (#10442) + * remove ABPP field as NBITS IMAGE_STRUCTURE metadata item, instead of NBPP + * CreateCopy(): support Blue,Green,Red[,other] color interpretation ordering + (#10508) + * when built as plugin, make sure to register the RPFTOC and ECRGTOC drivers too + +OGCAPI driver: + * combine CURL error message and data payload (when it exists) to form error + message + +OpenFileGDB driver: + * Identify: if nOpenFlags == GDAL_OF_RASTER, and the dataset is local, check + file extensions to better identify + * use GDALIsValueInRange<> to avoid potential undefined behavior casts + +PDF driver: + * PDFium backend: update to PDFium 6677 + +PDS4 driver: + * Create(): open file(s) in wb+ mode if possible + * flip image along horizontal axis when horizontal_display_direction = Right + to Left (#10429) + +S102 driver: + * GDALPamDataset::XMLInit(): preserve DerivedDataset nodes that affect S102 + PAM saving + * add (limited) support for IHO S102 v3.0 specification (#10779) + +SAFE (Sentinel1): + * report a FOOTPRINT metadata item + * report failure to opening a band dataset as a warning + +STACIT driver: + * correctly return the STACIT driver as the dataset's driver, instead of VRT + * support top-level Feature in addition to FeatureCollection + +SRTMHGT driver: + * add support for reading/wrinting 0.5 deg resolution datasets (#10514) + +TileDB driver: + * implement GetNoDataValue()/SetNoDataValue() + * implement BuildOverviews() (for dataset created with CREATE_GROUP=YES) + * Default to CREATE_GROUP=YES when creating datasets + * allow to potentially read/write more than 2GB at once + * IRasterIO(): fix checks related to pixel/line/band spacing for optimized code paths + * CopySubDatasets(): support very large number of blocks and very large block size + * CreateCopy(): return nullptr in error cases + * CreateCopy(): do not force returned dataset to be in read-only mode + * IRasterIO(): avoid reading out-of-raster with TILEDB_ATTRIBUTE creation option, + when the block size is not a multiple of the raster size + +VICAR driver: + * handle VICAR header being located beyond 2 GB within PDS3 file + +VRT driver: + * multi-thread IRasterIO() in 'simple' situations + * reduce mutex contention, particularly useful for multithreading of remote + sources + * GetDataCoverageStatus(): implement special case on a single source covering + the whole dataset + * GDALAutoCreateWarpedVRT(): ignore src nodata value if it cannot be represented + in the source band data type + * VRTComplexSource::RasterIO(): speed-up pixel copy in more cases + * Warped VRT: instantiate overview bands in a lazy fashion for faster execution + * VRTWarpedDataset::IRasterIO(): avoid a memory allocation and pixel copy when + possible + * VRTWarpedDataset::IRasterIO(): optimize I/O when requesting whole image at a + resolution that doesn't match an overview + * allow it to be partially disabled if GDAL built with GDAL_ENABLE_VRT_DRIVER=OFF + * use GDAL_OF_VERBOSE_ERROR flag in vrt:// and pansharpened modes + +WMTS driver: + * when reading a WMTS capabilities file, use in priority Operation.GetCapabilities.DCP.HTTP + to retrieve the URL (#10732) + * try to be robust to servers using CRS instead of SRS in 1.1.1 mode (#10922) + +XYZ driver: + * add COLUMN_ORDER open option + +Zarr driver: + * Zarr V2 creation: fix bug when creating dataset with partial blocks and need + to re-read them in the writing process when compression is involved (#11016) + * Allow int64 attributes (#10065) + * SerializeNumericNoData(): use CPLJSonObject::Add(uint64_t) to avoid + potential undefined behavior casts + * Create(): remove created files / directories if an error occurs (#11023) + +## OGR 3.10.0 + +### Core + +* OGRSQL and SQLite dialect: add STDDEV_POP() and STDDEV_SAMP() aggregate functions +* SQL SQLite dialect: fix translation of "x IN (NULL)" with "recent" + (at least > 3.31.1) versions of SQLite3 +* OGRSQL: fix compliance of NOT and IN operators regarding NULL values +* OGRSQL: SQL expression tree to string: add missing parenthesis that could make + further evaluation of operator priority wrong +* OGRSQL: add SELECT expression [AS] OGR_STYLE HIDDEN to be able to specify + feature style string without generating a visible column (#10259) +* OGRSQL: use Kahan-Babuska-Neumaier algorithm for accurate SUM() +* OGRSQL: avoid going through string serialization for MIN(), MAX(), SUM(), + AVG() on numeric fields +* OGRSQL: do not query geometry column(s) when not needed +* SQLite SQL dialect: add MEDIAN, PERCENTILE, PERCENTILE_CONT and MODE + ordered-set aggregate functions +* SQLite/GPKG: extend gdal_get_pixel_value()/gdal_get_layer_pixel_value() + to support an interpolation method +* SQLite/GPKG: Add ST_Length(geom, use_ellipsoid) +* GetNextArrowArray() generic implementation: avoid calling + VSI_MALLOC_ALIGNED_AUTO_VERBOSE() with a zero size +* Arrow reading: generic code path (as used by GeoJSON): fix mis-handling of + timezones +* OGRFeature: optimizations while accessing field count +* OGRFeature: SetXXX() methods: more informative warning messages reporting + field name and value for out-of-range values +* Add OGRGeometry::BufferEx() method +* Add OGRGeometry::hasEmptyParts()/removeEmptyParts() +* Add OGRCurve::reversePoints(), and deprecated OGRLinearRing::reverseWindingOrder() +* Add OGRGeometryCollection::stealGeometry() +* Add OGR_G_GeodesicLength() and OGRCurve/OGRSurface/OGRGeometryCollection::get_GeodesicLength() +* make OGR_G_GetLength() work on surfaces, suming the length of their + exterior and interior rings. +* OGR geometry classes: add a bool return type for methods that can fail +* OGR geometry classes: mark default constructors directly in .h and removed + useless overridden destructor for better code generation +* MakeValid(METHOD=STRUCTURE): make sure to return a MULTIPOLYGON if input is + MULTIPOLYGON (#10819) +* GML geometry reader: add support for gml:OrientableCurve (#10301) +* GenSQL layer: implement OLCFastGetArrowStream when underlying layer does and + for very simple SQL statements +* WKT geometry importer: accept (non conformant) PointZ/PointZM without space as + generated by current QGIS versions +* OGRLineString::SetPoint(): avoid int overflow if passing iPoint = INT_MAX +* OGRCurveCollection::addCurveDirectly(): avoid int overflow if adding to a + already huge collection +* OGRGeometryCollection::addGeometryDirectly(): avoid int overflow if adding to + a already huge collection +* OGRGeometryFactory::transformWithOptions(): in WRAPDATELINE=YES mode, return a + multi polygon if a input multi polygon has been provided (#10686) +* OGRGeometryFactory::transformWithOptions(): deal with polar or anti-meridian + discontinuities when going from projected to (any) geographic CRS +* OGRProjCT::TransformWithErrorCodes(): speed-up by avoiding OSRGetProjTLSContext() + when possible +* Add OGRWKBTransform() for in-place coordinate transformation of WKB geometries +* OGR_GreatCircle_ API: do not hardcode Earth radius +* ogr_core.h: suppress warning when building with -Wpedantic for C < 23 (#2322) + +### OGRSpatialReference + +* OGRSpatialReference::FindMatches(): improve when input SRS doesn't have + expected axis order +* OGRSpatialReference::EPSGTreatsAsLatLong()/EPSGTreatsAsNorthingEasting(): + remove the check on the EPSG authority +* Add OSRGetAuthorityListFromDatabase() to get the list of CRS authorities used + in the PROJ database. + +### Utilities + +* ogr2ogr: add -skipinvalid to skip features whose geometry is not valid w.r.t + Simple Features +* ogr2ogr: error out if WKT argument of -clipsrc/-clipdst is an invalid geometry + (#10289) +* ogr2ogr: speed-up -clipsrc/-clipdst by avoiding GEOS when possible +* ogr2ogr: speed-up -t_srs in Arrow code path using multi-threaded coordinate + transformation +* ogr2ogr: optim: call GetArrowStream() only once on source layer when using + Arrow interface +* ogr2ogr: fix -explodecollections on empty geometries (#11067) +* validate_gpkg.py: make it robust to CURRENT_TIMESTAMP instead of 'now' + +### Vector drivers + +Multi-driver changes: + * Arrow, CSV, ESRIJSON, JSONFG, GeoJSON, GeoJSONSeq, GML, GTFS, LVBAG, NAS, + OAPIF, TopoJSON: + relax identificationchecks when papszAllowedDrivers[] contains only the + driver name + * GeoJSON like driver: avoid fetching unrecognized HTTP dataset more than once + +Arrow ecosystem: + * Arrow/Parquet/generic arrow: add write support for arrow.json extension + * Add a Arrow VSI file system (for libarrow >= 16.0) allowing to use GDAL + VSI file systems as libarrow compatible file systems. + * Add (minimum) support for libarrow 18.0.0 + +Arrow driver + * add read support for StringView and BinaryView (but not in OGR generic Arrow + code) + * use recommended item names for GeoArrow [multi]line, [multi]polygon, multipoint + +CSV driver: + * error out if invalid/inconsistent value for GEOMETRY layer creation option + (#10055) + * allow inf, -inf and nan as numeric values + * emit warning when reading invalid WKT (#10496) + +CSW driver: + * make it buildable as plugin + +DGN driver: + * add ENCODING open option and creation option (#10630) + +DXF driver: + * add a DXF_CLOSED_LINE_AS_POLYGON=YES/NO configuration option (#10153) + +ESRIJSON driver: + * make it able to parse response of some CadastralSpecialServices APIs (#9996) + * use 'alias' field member to set OGR alternative field name + +FileGDB/OpenFileGDB drivers: + * update (and unify) list of reserved keywords that can't be used for column + and table names (#11094) + +JSONFG driver: + * avoid Polyhedron/Prism geometry instantiation during initial scan + +GeoJSON driver: + * make it (and companion TopoJSON, ESRIJSON, GeoJSONSeq) optional (but must be + explicitly disabled) and buildable as plugin + * avoid false-positive identification as TopoJSON + +GeoJSONSeq driver: + * add a WRITE_BBOX layer creation option + +GML driver: + * XSD parser: fix to resolve schema imports using open option USE_SCHEMA_IMPORT + (#10500) + * make it buildable as plugin if NAS driver is explicitly disabled + * add a GML_DOWNLOAD_SCHEMA config option matching the DOWNLOAD_SCHEMA open + option (and deprecate undocumented GML_DOWNLOAD_WFS_SCHEMA) + +GPKG driver: + * prevent from creating field with same name, or with the name of the geometry + field + * CreateField(): check we are not reaching the max number of fields + * SQLite/GPKG: turn on SQLite 'PRAGMA secure_delete=1' by default + +HANA driver: + * Add support for REAL_VECTOR type (#10499) + * Add support for fast extent estimation (#10543) + +KML driver: + * make it optional and buildable as plugin + * writer: generate a Placemark id + +LIBKML driver: + * writer: validate longitude, latitude to be in range (#10483) + * writer: set name of NetworkLink from NAME layer creation option (#10507) + * writer: dump feature when its geometry cannot be written (#10829) + * on reading of directory KML datasets, don't consider the root doc.kml as a layer + +MapInfo driver: + * make it optional and buildable as plugin + * implement read/write support for MapInfo logical type to OGR OFSTBoolean + * Add UTF-8 encoding + * Disable table fields "laundering" for non-neutral charset + * Add 'STRICT_FIELDS_NAME_LAUNDERING' creation option + * better deal with EPSG:3301 'Estonian Coordinate System of 1997' + +Miramon driver: + * various memory leak fixes on corrupted datasets + +OAPIF driver: + * combine CURL error message and data payload (when it exists) to form error + message (#10653) + * make it buildable as plugin (independently of WFS driver) + * add a DATETIME open option (#10909) + +OCI driver: + * OCI: use TIMESTAMP(3) and tweak NLS_TIME[STAMP][_TZ]_FORMAT to accept + milliseconds (#11057) + +ODBC driver: + * add GDAL_DMD_LONGNAME + +OpenFileGDB driver: + * add partial read-only support for tables with 64-bit ObjectIDs + * more informative warning message when opening a dataset with a .cdf file and + FileGDB driver isn't there + * error out explicitly when attempting to create an index on multiple columns + +OSM driver: + * add a \[general\] section at top of osmconf.ini to make it INI compliant (and + Python's configparser friendly) + * actually reserve memory for /vsimem/ temp files + +Parquet driver: + * dataset (multi-file typically) mode: enable use of bounding box columns + for spatial filter; optimize spatial filtering + * dataset mode: implement SetIgnoredFields() and SetAttributeFilter() + * dataset mode: detect bbox geometry column when opening current Overture Maps + * dataset mode: make sure all files are closed before closing the GDALDataset + +PDF driver: + * reader: fixes to handle recursive resources, /OC property attached to a + XObjet and an empty UTF-16 layer name (#11034) + +PostgreSQL driver: + * OGR_PG_SKIP_CONFLICTS: optionally insert with ON CONFLICT DO NOTHING (#10156) + * avoid error when the original search_path is empty + +Shapefile driver: + * make it optional (but must be explicitly disabled) and buildable as plugin + * Shapelib: resync'ed with upstream + +SQLite driver: + * run deferred table creation before StartTransaction + * avoid some potential O(n^2) issues with n=field_count + +TileDB driver: + * use GEOM_WKB type when creating geometry columns with TileDB >= 2.21 + +VRT driver: + * OGRWarpedVRT: use faster SetFrom() implementation (#10765) + * UnionLayer: avoid some potential O(n^2) issues with n=field_count + +WFS driver: + * make it buildable as plugin + +## SWIG bindings + +* Python/Java: replace sprintf() with snprintf() to avoid warnings on OSX +* fix memleak in gdal.GetConfigOptions() + +### Python bindings + +* generate launcher shell/bat scripts for Python scripts in /swig/python/bin +* make GetStatistics() and ComputeStatistics() return None in case of error (#10462) +* Make ogr.DataSource a synonym of gdal.Dataset +* Remove ogr.Driver +* do not emit warnings about not having used UseExceptions() if run under + gdal.ExceptionMgr() +* avoid gdal.ExceptionMgr() to re-throw a GDAL exception already caught under it +* avoid exception emitted and caught under gdal.ExceptionMgr() to cause later issues +* Python scripts: use local exception manager, instead of global UseExceptions() +* check validity of GDALAccess flag passed to gdal.Open() +* make MDArray.Write(array_of_strings) work with a 0-d string variable +* Avoid linear scan in gdal_array.NumericTypeCodeToGDALTypeCode (#10694) +* Dataset.Close(): invalidate children before closing dataset +* __init__.py: remove calls to warnings.simplefilter() (#11140) +* fix compatibility issue with SWIG 4.3.0 and PYTHONWARNINGS=error + +### Java bindings + +* Make sure a valid UTF-8 string is passed to NewStringUTF() +* OGR module: add various xxxxAsByteArray() method that return a byte[] when + content is not UTF-8 (#10521, #10630) + +# GDAL/OGR 3.9.3 Release Notes + +GDAL 3.9.3 is a bugfix release. + +## Build + +* Java bindings: remove unneeded dependency on Java AWT +* Use the right header for std::endian cpl_conv.cpp (C++20 compilation) +* Fix build failure with upstream netcdf caused by _FillValue macro renaming + +## GDAL 3.9.3 + +### Port + +* /vsitar/: fix support of /vsitar/ of /vsitar/ (#10821) +* CPLGetValueType(): do not recognize '01' as integer, but as string + (Toblerity/Fiona#1454) + +### Algorithms + +* Geoloc array: fix bad usage of path API that resulted in temporary files + not being created where expected (#10671) +* GDALCreateGeoLocTransformer(): fix inverted logic to decide for a debug + message +* GDALCreateGeoLocTransformer(): increase threshold to use GTiff geoloc + working datasets to 24 megapixels (#10809) +* GDALGeoLocDatasetAccessors: use smaller, but more, cached tiles (#10809) +* Warper: fix too lax heuristics about antimeridian warping for Avg/Sum/Q1/ + Q3/Mode algorithms (#10892) + +### Core + +* Fix GDALDataTypeUnion() to check that the provided value fits into eDT +* GDALRegenerateOverviewsMultiBand(): make sure than when computing large + reduction factors (like > 1024) on huge rasters does not lead to excessive + memory requirements +* Overview: fix nearest resampling to be exact with all data types (#10758). + Also make sure that for other resampling methods, the working data type + is large enough (e.g using Float64 for Int32/UInt32/Int64/UInt64). + +### Raster utilities + +* gdal_translate/GDALOverviewDataset: fix half-pixel shift issue when + rescaling RPC (#10600) +* gdaldem color-relief: fix issues with entry at 0 and -exact_color_entry + mode, and other issues +* gdalwarp: fix crash/infinite loop when using -tr one a 1x1 blank raster + (3.8.0 regression) +* gdalwarp: be more robust to numerical instability when selecting overviews + (#10873) +* gdal_contour: Fix regression when fixed level == raster max (#10854) + +### Raster drivers + +DIMAP driver: + * emit verbose error message if not able to open image file (#10928) + +GeoRaster driver: + * Preserve quote in the connection string to the GeoRaster driver so that + Oracle Database wallet can be supported (#10869) + +GRIB: + * adjust longitude range from \[180, xxx\] to \[-180, xxx\] (#10655) + +GTiff driver: + * do not query TIFFTAG_TRANSFERFUNCTION if m_nBitsPerSample > 24 (#10875) + * fix to not delete DIMAP XML files when cleaning overviews on a DIMAP2 + GeoTIFF file with external overviews + +JPEG driver: + * Fix inverted handling of GDAL_ERROR_ON_LIBJPEG_WARNING + +JP2KAK driver: + * fix data corruption when creating multi-band tiled with the stripe + compressor code path (#10598) + +KEA driver: + * fix overview writing + +MrSID driver: + * prevent infinite recursion in IRasterIO() in some cases (#10697) + +netCDF driver: + * honour BAND_NAMES creation option in CreateCopy() (#10646) + +NITF driver: + * properly take into account comma-separated list of values for JPEG2000 + QUALITY when JPEG2000_DRIVER=JP2OpenJPEG (#10927) + * fix parsing of CSCSDB DES + +OpenFileGDB raster: + * do not generate debug 'tmp.jpg' file when reading JPEG tiles + +PDF driver: + * avoid 'Non closed ring detected' warning when reading neatlines from OGC + Best Practice encoding + +TileDB driver: + * make Identify() method return false if passed object is not a directory + +VRT driver: + * VRTSourcedRasterBand::IRasterIO(): initialize output buffer to nodata + value if VRT band type is Int64 or UInt64 + * VRTComplexSource::RasterIO(): use double working data type for more + source or VRT data types + * VRTComplexSource::RasterIO(): speed-up pixel copy in more cases (#10809) + * VRTProcessedDataset: fix issue when computing RasterIO window on + auxiliary datasets on right-most/bottom-most tiles + +## OGR 3.9.3 + +### Core + +* Make OGRSFDriver::TestCapability(ODrCCreateDataSource) work with + defered-loaded drivers (#10783) +* MEM layer: fix UpdateFeature() that didn't mark the layer as updated, + which caused GeoJSON files to not be updated (qgis/QGIS#57736) + +### Vector drivers + +FlatGeobuf driver: + * Fix reading of conformant single-part MultiLineString (#10774) + +GeoPackage driver: + * OGR_GPKG_FillArrowArray_Step(): more rigorous locking + +GMLAS driver: + * make it robust to XML billion laugh attack + +JSONFG driver: + * accept coordRefSys starting with https://www.opengis.net/def/crs/ + +NAS driver: + * make it robust to XML billion laugh attack + +OpenFileGDB driver: + * add missing GetIndexCount() in FileGDBTable::CreateIndex + * fix writing a Int32 field with value -21121 + * exclude straight line segments when parsing arcs (#10763) + +Parquet driver: + * fix crash when using SetIgnoredFields() + SetSpatialFilter() on + GEOMETRY_ENCODING=GEOARROW layers with a covering bounding box + (qgis/QGIS#58086) + +PostgreSQL/PGDump drivers: + * properly truncates identifiers exactly of 64 characters (#10907) + +PostgreSQL driver: + * ensure current user has superuser privilege beore attemption to create + event trigger for metadata table (#10925) + +Shapefile driver: + * Add new shapelib API functions to the symbol rename header + +SQLite/GPKG drivers: + * fix potential double-free issue when concurrently closing datasets when + Spatialite is available + +## Python bindings + +* Silence SWIG 'detected a memory leak' message (#4907) +* fix passing a dict value to the transformerOptions argument of gdal.Warp() + (#10919) + # GDAL/OGR 3.9.2 Release Notes GDAL 3.9.2 is a bugfix release. diff --git a/README.md b/README.md index 4d458ac82db1..b76a3c4f35a8 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,9 @@ GDAL - Geospatial Data Abstraction Library [![Build Status](https://github.com/OSGeo/gdal/actions/workflows/clang_static_analyzer.yml/badge.svg)](https://github.com/osgeo/gdal/actions?query=workflow%3A%22CLang+Static+Analyzer%22+branch%3Amaster) [![Build Status](https://github.com/OSGeo/gdal/actions/workflows/code_checks.yml/badge.svg)](https://github.com/osgeo/gdal/actions?query=workflow%3A%22Code+Checks%22+branch%3Amaster) [![Build Status](https://github.com/OSGeo/gdal/actions/workflows/conda.yml/badge.svg)](https://github.com/osgeo/gdal/actions?query=workflow%3A%22Conda%22+branch%3Amaster) -[![Build Status](https://app.travis-ci.com/OSGeo/gdal.svg?branch=master)](https://app.travis-ci.com/OSGeo/gdal) [![Build Status](https://scan.coverity.com/projects/749/badge.svg?flat=1)](https://scan.coverity.com/projects/gdal) [![Documentation build Status](https://github.com/OSGeo/gdal/workflows/Docs/badge.svg)](https://github.com/osgeo/gdal/actions?query=workflow%3A%22Docs%22+branch%3Amaster) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/gdal.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:gdal) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/gdal.svg)](https://issues.oss-fuzz.com/issues?q=status:open%20gdal) [![Coverage Status](https://coveralls.io/repos/github/OSGeo/gdal/badge.svg?branch=master)](https://coveralls.io/github/OSGeo/gdal?branch=master) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8250/badge)](https://www.bestpractices.dev/projects/8250) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/OSGeo/gdal/badge)](https://securityscorecards.dev/viewer/?uri=github.com/OSGeo/gdal) @@ -27,7 +26,6 @@ GDAL is an open source MIT licensed translator library for raster and vector geo * GIT repository: https://github.com/OSGeo/gdal * Bug tracker: https://github.com/OSGeo/gdal/issues * Download: https://download.osgeo.org/gdal -* Wiki: https://trac.osgeo.org/gdal - Various user and developer contributed documentation and hints * Mailing list: https://lists.osgeo.org/mailman/listinfo/gdal-dev [//]: # (numfocus-fiscal-sponsor-attribution) diff --git a/VERSION b/VERSION index 30291cba2230..afad818663d0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.10.0 +3.11.0 diff --git a/alg/CMakeLists.txt b/alg/CMakeLists.txt index c4f71ee521a1..98a86899f765 100644 --- a/alg/CMakeLists.txt +++ b/alg/CMakeLists.txt @@ -57,11 +57,15 @@ target_compile_options(alg PRIVATE $<$:${GDAL_CXX_WARNING_ target_compile_options(alg PRIVATE $<$:${GDAL_C_WARNING_FLAGS}>) target_include_directories( - alg PRIVATE $ $ + alg PRIVATE $ $ $) set_property(TARGET alg PROPERTY POSITION_INDEPENDENT_CODE ${GDAL_OBJECT_LIBRARIES_POSITION_INDEPENDENT_CODE}) target_sources(${GDAL_LIB_TARGET_NAME} PRIVATE $) +if (GDAL_ENABLE_DRIVER_GTIFF) + target_include_directories(alg PRIVATE $) +endif() + if (GDAL_USE_GEOS) target_compile_definitions(alg PRIVATE -DHAVE_GEOS=1) gdal_target_link_libraries(alg PRIVATE ${GEOS_TARGET}) diff --git a/alg/armadillo_headers.h b/alg/armadillo_headers.h index 6d4fb780103a..d3210e1c4a76 100644 --- a/alg/armadillo_headers.h +++ b/alg/armadillo_headers.h @@ -8,23 +8,7 @@ ****************************************************************************** * 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #ifndef ARMADILLO_HEADERS_H diff --git a/alg/contour.cpp b/alg/contour.cpp index 7a96c1397932..9c74574b1a95 100644 --- a/alg/contour.cpp +++ b/alg/contour.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2007-2013, Even Rouault * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "level_generator.h" @@ -196,7 +180,7 @@ struct PolygonContourWriter std::unique_ptr currentGeometry_ = {}; OGRPolygon *currentPart_ = nullptr; OGRContourWriterInfo *poInfo_ = nullptr; - double currentLevel_; + double currentLevel_ = 0; double previousLevel_ = 0; }; @@ -749,6 +733,33 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer, } } } + + // Largest requested level (levels are sorted) + const double maxLevel{fixedLevels.back()}; + + // If the maximum raster value is smaller than the last requested + // level, select the requested level that is just above the + // maximum raster value + if (maxLevel > dfMaximum) + { + for (size_t i = fixedLevels.size() - 1; i > 0; --i) + { + if (fixedLevels[i] <= dfMaximum) + { + dfMaximum = fixedLevels[i + 1]; + break; + } + } + } + + // If the maximum raster value is equal to the last requested + // level, add a small value to the maximum to avoid skipping the + // last level polygons + if (maxLevel == dfMaximum) + { + dfMaximum = std::nextafter( + dfMaximum, std::numeric_limits::infinity()); + } } PolygonContourWriter w(&oCWI, dfMinimum); diff --git a/alg/delaunay.c b/alg/delaunay.c index 526f93a6631a..cb7f9484d7d8 100644 --- a/alg/delaunay.c +++ b/alg/delaunay.c @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #if defined(__MINGW32__) || defined(__MINGW64__) diff --git a/alg/gdal_alg.h b/alg/gdal_alg.h index 604fc48b00ae..e92cd6625313 100644 --- a/alg/gdal_alg.h +++ b/alg/gdal_alg.h @@ -9,23 +9,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2008-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_ALG_H_INCLUDED diff --git a/alg/gdal_alg_priv.h b/alg/gdal_alg_priv.h index b7b3a3a35ff2..cb0645eb676a 100644 --- a/alg/gdal_alg_priv.h +++ b/alg/gdal_alg_priv.h @@ -10,23 +10,7 @@ * Copyright (c) 2008, Andrey Kiselev * Copyright (c) 2010-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_ALG_PRIV_H_INCLUDED @@ -173,6 +157,7 @@ constexpr const char *GDAL_APPROX_TRANSFORMER_CLASS_NAME = "GDALApproxTransformer"; constexpr const char *GDAL_GEN_IMG_TRANSFORMER_CLASS_NAME = "GDALGenImgProjTransformer"; +constexpr const char *GDAL_RPC_TRANSFORMER_CLASS_NAME = "GDALRPCTransformer"; bool GDALIsTransformer(void *hTransformerArg, const char *pszClassName); @@ -206,6 +191,8 @@ bool GDALTransformIsTranslationOnPixelBoundaries( bool GDALTransformIsAffineNoRotation(GDALTransformerFunc pfnTransformer, void *pTransformerArg); +bool GDALTransformHasFastClone(void *pTransformerArg); + typedef struct _CPLQuadTree CPLQuadTree; typedef struct diff --git a/alg/gdal_interpolateatpoint.cpp b/alg/gdal_interpolateatpoint.cpp index c96ca3a7dab7..171106f3fb03 100644 --- a/alg/gdal_interpolateatpoint.cpp +++ b/alg/gdal_interpolateatpoint.cpp @@ -10,29 +10,15 @@ * Copyright (c) 2008-2012, Even Rouault * Copyright (c) 2024, Javier Jimenez Shaw * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_interpolateatpoint.h" #include "gdalresamplingkernels.h" +#include "gdal_vectorx.h" + #include #include @@ -52,11 +38,16 @@ template <> bool areEqualReal(double dfNoDataValue, std::complex dfOut) template bool GDALInterpExtractValuesWindow(GDALRasterBand *pBand, std::unique_ptr &cache, - int nX, int nY, int nWidth, int nHeight, - T *padfOut) + gdal::Vector2i point, + gdal::Vector2i dimensions, T *padfOut) { constexpr int BLOCK_SIZE = 64; + const int nX = point.x(); + const int nY = point.y(); + const int nWidth = dimensions.x(); + const int nHeight = dimensions.y(); + // Request the DEM by blocks of BLOCK_SIZE * BLOCK_SIZE and put them // in cache if (!cache) @@ -169,29 +160,32 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, std::unique_ptr &cache, const double dfXIn, const double dfYIn, T &out) { - const int nRasterXSize = pBand->GetXSize(); - const int nRasterYSize = pBand->GetYSize(); + const gdal::Vector2i rasterSize{pBand->GetXSize(), pBand->GetYSize()}; + const gdal::Vector2d inLoc{dfXIn, dfYIn}; + int bGotNoDataValue = FALSE; const double dfNoDataValue = pBand->GetNoDataValue(&bGotNoDataValue); - if (dfXIn < 0 || dfXIn > nRasterXSize || dfYIn < 0 || dfYIn > nRasterYSize) + if (inLoc.x() < 0 || inLoc.x() > rasterSize.x() || inLoc.y() < 0 || + inLoc.y() > rasterSize.y()) { return FALSE; } // Downgrade the interpolation algorithm if the image is too small - if ((nRasterXSize < 4 || nRasterYSize < 4) && + if ((rasterSize.x() < 4 || rasterSize.y() < 4) && (eResampleAlg == GRIORA_CubicSpline || eResampleAlg == GRIORA_Cubic)) { eResampleAlg = GRIORA_Bilinear; } - if ((nRasterXSize < 2 || nRasterYSize < 2) && + if ((rasterSize.x() < 2 || rasterSize.y() < 2) && eResampleAlg == GRIORA_Bilinear) { eResampleAlg = GRIORA_NearestNeighbour; } - auto outOfBorderCorrection = [](int dNew, int nRasterSize, int nKernelsize) + auto outOfBorderCorrectionSimple = + [](int dNew, int nRasterSize, int nKernelsize) { int dOutOfBorder = 0; if (dNew < 0) @@ -205,7 +199,17 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, return dOutOfBorder; }; - auto dragReadDataInBorder = + auto outOfBorderCorrection = + [&outOfBorderCorrectionSimple, + &rasterSize](gdal::Vector2i input, int nKernelsize) -> gdal::Vector2i + { + return { + outOfBorderCorrectionSimple(input.x(), rasterSize.x(), nKernelsize), + outOfBorderCorrectionSimple(input.y(), rasterSize.y(), + nKernelsize)}; + }; + + auto dragReadDataInBorderSimple = [](T *adfElevData, int dOutOfBorder, int nKernelSize, bool bIsX) { while (dOutOfBorder < 0) @@ -238,9 +242,18 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, dOutOfBorder--; } }; + auto dragReadDataInBorder = [&dragReadDataInBorderSimple]( + T *adfElevData, gdal::Vector2i dOutOfBorder, + int nKernelSize) -> void + { + dragReadDataInBorderSimple(adfElevData, dOutOfBorder.x(), nKernelSize, + true); + dragReadDataInBorderSimple(adfElevData, dOutOfBorder.y(), nKernelSize, + false); + }; - auto applyBilinearKernel = [&](double dfDeltaX, double dfDeltaY, - T *adfValues, T &pdfRes) -> bool + auto applyBilinearKernel = [&](gdal::Vector2d dfDelta, T *adfValues, + T &pdfRes) -> bool { if (bGotNoDataValue) { @@ -256,18 +269,19 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, return FALSE; } } - const double dfDeltaX1 = 1.0 - dfDeltaX; - const double dfDeltaY1 = 1.0 - dfDeltaY; + const gdal::Vector2d dfDelta1 = 1.0 - dfDelta; - const T dfXZ1 = adfValues[0] * dfDeltaX1 + adfValues[1] * dfDeltaX; - const T dfXZ2 = adfValues[2] * dfDeltaX1 + adfValues[3] * dfDeltaX; - const T dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; + const T dfXZ1 = + adfValues[0] * dfDelta1.x() + adfValues[1] * dfDelta.x(); + const T dfXZ2 = + adfValues[2] * dfDelta1.x() + adfValues[3] * dfDelta.x(); + const T dfYZ = dfXZ1 * dfDelta1.y() + dfXZ2 * dfDelta.y(); pdfRes = dfYZ; return TRUE; }; - auto apply4x4Kernel = [&](double dfDeltaX, double dfDeltaY, T *adfValues, + auto apply4x4Kernel = [&](gdal::Vector2d dfDelta, T *adfValues, T &pdfRes) -> bool { T dfSumH = 0.0; @@ -280,14 +294,13 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation. - const int dKernIndX = k_j - 1; - const int dKernIndY = k_i - 1; + const gdal::Vector2i dKernInd = {k_j - 1, k_i - 1}; + const gdal::Vector2d fPoint = dKernInd.cast() - dfDelta; const double dfPixelWeight = eResampleAlg == GDALRIOResampleAlg::GRIORA_CubicSpline - ? CubicSplineKernel(dKernIndX - dfDeltaX) * - CubicSplineKernel(dKernIndY - dfDeltaY) - : CubicKernel(dKernIndX - dfDeltaX) * - CubicKernel(dKernIndY - dfDeltaY); + ? CubicSplineKernel(fPoint.x()) * + CubicSplineKernel(fPoint.y()) + : CubicKernel(fPoint.x()) * CubicKernel(fPoint.y()); // Create a sum of all values // adjusted for the pixel's calculated weight. @@ -314,32 +327,24 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, { // Convert from upper left corner of pixel coordinates to center of // pixel coordinates: - const double dfX = dfXIn - 0.5; - const double dfY = dfYIn - 0.5; - const int dX = static_cast(std::floor(dfX)); - const int dY = static_cast(std::floor(dfY)); - const double dfDeltaX = dfX - dX; - const double dfDeltaY = dfY - dY; - - const int dXNew = dX - 1; - const int dYNew = dY - 1; + const gdal::Vector2d df = inLoc - 0.5; + const gdal::Vector2i d = df.floor().template cast(); + const gdal::Vector2d delta = df - d.cast(); + const gdal::Vector2i dNew = d - 1; const int nKernelSize = 4; - const int dXOutOfBorder = - outOfBorderCorrection(dXNew, nRasterXSize, nKernelSize); - const int dYOutOfBorder = - outOfBorderCorrection(dYNew, nRasterYSize, nKernelSize); + const gdal::Vector2i dOutOfBorder = + outOfBorderCorrection(dNew, nKernelSize); // CubicSpline interpolation. T adfReadData[16] = {0.0}; - if (!GDALInterpExtractValuesWindow(pBand, cache, dXNew - dXOutOfBorder, - dYNew - dYOutOfBorder, nKernelSize, - nKernelSize, adfReadData)) + if (!GDALInterpExtractValuesWindow(pBand, cache, dNew - dOutOfBorder, + {nKernelSize, nKernelSize}, + adfReadData)) { return FALSE; } - dragReadDataInBorder(adfReadData, dXOutOfBorder, nKernelSize, true); - dragReadDataInBorder(adfReadData, dYOutOfBorder, nKernelSize, false); - if (!apply4x4Kernel(dfDeltaX, dfDeltaY, adfReadData, out)) + dragReadDataInBorder(adfReadData, dOutOfBorder, nKernelSize); + if (!apply4x4Kernel(delta, adfReadData, out)) return FALSE; return TRUE; @@ -348,47 +353,38 @@ bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, { // Convert from upper left corner of pixel coordinates to center of // pixel coordinates: - const double dfX = dfXIn - 0.5; - const double dfY = dfYIn - 0.5; - const int dX = static_cast(std::floor(dfX)); - const int dY = static_cast(std::floor(dfY)); - const double dfDeltaX = dfX - dX; - const double dfDeltaY = dfY - dY; - + const gdal::Vector2d df = inLoc - 0.5; + const gdal::Vector2i d = df.floor().template cast(); + const gdal::Vector2d delta = df - d.cast(); const int nKernelSize = 2; - const int dXOutOfBorder = - outOfBorderCorrection(dX, nRasterXSize, nKernelSize); - const int dYOutOfBorder = - outOfBorderCorrection(dY, nRasterYSize, nKernelSize); + const gdal::Vector2i dOutOfBorder = + outOfBorderCorrection(d, nKernelSize); // Bilinear interpolation. T adfReadData[4] = {0.0}; - if (!GDALInterpExtractValuesWindow(pBand, cache, dX - dXOutOfBorder, - dY - dYOutOfBorder, nKernelSize, - nKernelSize, adfReadData)) + if (!GDALInterpExtractValuesWindow(pBand, cache, d - dOutOfBorder, + {nKernelSize, nKernelSize}, + adfReadData)) { return FALSE; } - dragReadDataInBorder(adfReadData, dXOutOfBorder, nKernelSize, true); - dragReadDataInBorder(adfReadData, dYOutOfBorder, nKernelSize, false); - if (!applyBilinearKernel(dfDeltaX, dfDeltaY, adfReadData, out)) + dragReadDataInBorder(adfReadData, dOutOfBorder, nKernelSize); + if (!applyBilinearKernel(delta, adfReadData, out)) return FALSE; return TRUE; } else { - const int dX = static_cast(dfXIn); - const int dY = static_cast(dfYIn); - T dfOut{}; - if (!GDALInterpExtractValuesWindow(pBand, cache, dX, dY, 1, 1, - &dfOut) || - (bGotNoDataValue && areEqualReal(dfNoDataValue, dfOut))) + const gdal::Vector2i d = inLoc.cast(); + T adfOut[1] = {}; + if (!GDALInterpExtractValuesWindow(pBand, cache, d, {1, 1}, adfOut) || + (bGotNoDataValue && areEqualReal(dfNoDataValue, adfOut[0]))) { return FALSE; } - out = dfOut; + out = adfOut[0]; return TRUE; } diff --git a/alg/gdal_interpolateatpoint.h b/alg/gdal_interpolateatpoint.h index c0e8b3170ba3..e92deaf7683e 100644 --- a/alg/gdal_interpolateatpoint.h +++ b/alg/gdal_interpolateatpoint.h @@ -10,23 +10,7 @@ * Copyright (c) 2008-2012, Even Rouault * Copyright (c) 2024, Javier Jimenez Shaw * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_INTERPOLATEATPOINT_H_INCLUDED diff --git a/alg/gdal_octave.cpp b/alg/gdal_octave.cpp index 63d17dbcd7c0..ff636718f305 100644 --- a/alg/gdal_octave.cpp +++ b/alg/gdal_octave.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2012, Andrew Migal * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_simplesurf.h" diff --git a/alg/gdal_rpc.cpp b/alg/gdal_rpc.cpp index 83827d7fc735..fb7e415f225f 100644 --- a/alg/gdal_rpc.cpp +++ b/alg/gdal_rpc.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2009-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -48,6 +32,7 @@ #include "gdal.h" #include "gdal_interpolateatpoint.h" #include "gdal_mdreader.h" +#include "gdal_alg_priv.h" #include "gdal_priv.h" #if defined(__x86_64) || defined(_M_X64) #define USE_SSE2_OPTIM @@ -837,7 +822,7 @@ void *GDALCreateRPCTransformerV2(const GDALRPCInfoV2 *psRPCInfo, int bReversed, memcpy(psTransform->sTI.abySignature, GDAL_GTI2_SIGNATURE, strlen(GDAL_GTI2_SIGNATURE)); - psTransform->sTI.pszClassName = "GDALRPCTransformer"; + psTransform->sTI.pszClassName = GDAL_RPC_TRANSFORMER_CLASS_NAME; psTransform->sTI.pfnTransform = GDALRPCTransform; psTransform->sTI.pfnCleanup = GDALDestroyRPCTransformer; psTransform->sTI.pfnSerialize = GDALSerializeRPCTransformer; diff --git a/alg/gdal_simplesurf.cpp b/alg/gdal_simplesurf.cpp index 4a76243b64b8..7af8ba0332db 100644 --- a/alg/gdal_simplesurf.cpp +++ b/alg/gdal_simplesurf.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2012, Andrew Migal * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_simplesurf.h" diff --git a/alg/gdal_simplesurf.h b/alg/gdal_simplesurf.h index 872644f9ca12..d6d1b1e4b7fd 100644 --- a/alg/gdal_simplesurf.h +++ b/alg/gdal_simplesurf.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2012, Andrew Migal * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /** diff --git a/alg/gdal_tps.cpp b/alg/gdal_tps.cpp index be7159bc50aa..cb259c95e38f 100644 --- a/alg/gdal_tps.cpp +++ b/alg/gdal_tps.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2004, Frank Warmerdam * Copyright (c) 2011-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalapplyverticalshiftgrid.cpp b/alg/gdalapplyverticalshiftgrid.cpp index 74c99fb12314..a7d044cb2abd 100644 --- a/alg/gdalapplyverticalshiftgrid.cpp +++ b/alg/gdalapplyverticalshiftgrid.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2017, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/alg/gdalchecksum.cpp b/alg/gdalchecksum.cpp index e1f5e38f1b1d..39ee2ba21314 100644 --- a/alg/gdalchecksum.cpp +++ b/alg/gdalchecksum.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2007-2008, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalcutline.cpp b/alg/gdalcutline.cpp index f06ca95d2a6f..fee9a684d582 100644 --- a/alg/gdalcutline.cpp +++ b/alg/gdalcutline.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2008, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdaldither.cpp b/alg/gdaldither.cpp index 7365168f1a46..46353ab6ec8e 100644 --- a/alg/gdaldither.cpp +++ b/alg/gdaldither.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007, 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. + * SPDX-License-Identifier: MIT ****************************************************************************** * * Notes: diff --git a/alg/gdalgenericinverse.cpp b/alg/gdalgenericinverse.cpp index cccc90ba22a9..f271efef5c49 100644 --- a/alg/gdalgenericinverse.cpp +++ b/alg/gdalgenericinverse.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/alg/gdalgenericinverse.h b/alg/gdalgenericinverse.h index 67005a1e15d4..2907500da9d0 100644 --- a/alg/gdalgenericinverse.h +++ b/alg/gdalgenericinverse.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALGENERICINVERSE_H diff --git a/alg/gdalgeoloc.cpp b/alg/gdalgeoloc.cpp index d053169304de..74ba0a74fadb 100644 --- a/alg/gdalgeoloc.cpp +++ b/alg/gdalgeoloc.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2021, CLS * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -2006,14 +1990,20 @@ void *GDALCreateGeoLocTransformerEx(GDALDatasetH hBaseDS, psTransform->bUseArray = !CPLTestBool(pszUseTempDatasets); else { - psTransform->bUseArray = nXSize < 16 * 1000 * 1000 / nYSize; - if (psTransform->bUseArray) + constexpr int MEGAPIXEL_LIMIT = 24; + psTransform->bUseArray = + nXSize < MEGAPIXEL_LIMIT * 1000 * 1000 / nYSize; + if (!psTransform->bUseArray) { CPLDebug("GEOLOC", "Using temporary GTiff backing to store backmap, because " - "geoloc arrays exceed 16 megapixels. You can set the " + "geoloc arrays require %d megapixels, exceeding the %d " + "megapixels limit. You can set the " "GDAL_GEOLOC_USE_TEMP_DATASETS configuration option to " - "NO to force RAM storage of backmap"); + "NO to force RAM storage of backmap", + static_cast(static_cast(nXSize) * nYSize / + (1000 * 1000)), + MEGAPIXEL_LIMIT); } } diff --git a/alg/gdalgeoloc.h b/alg/gdalgeoloc.h index 460bbc55aa0d..9ec7a657c970 100644 --- a/alg/gdalgeoloc.h +++ b/alg/gdalgeoloc.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALGEOLOC_H diff --git a/alg/gdalgeoloc_carray_accessor.h b/alg/gdalgeoloc_carray_accessor.h index f5da60deff82..53cdd3889554 100644 --- a/alg/gdalgeoloc_carray_accessor.h +++ b/alg/gdalgeoloc_carray_accessor.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /*! @cond Doxygen_Suppress */ diff --git a/alg/gdalgeoloc_dataset_accessor.h b/alg/gdalgeoloc_dataset_accessor.h index d78fd0334289..56113574c766 100644 --- a/alg/gdalgeoloc_dataset_accessor.h +++ b/alg/gdalgeoloc_dataset_accessor.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdalcachedpixelaccessor.h" @@ -53,13 +37,14 @@ class GDALGeoLocDatasetAccessors bool LoadGeoloc(bool bIsRegularGrid); public: - static constexpr int TILE_SIZE = 1024; - - GDALCachedPixelAccessor geolocXAccessor; - GDALCachedPixelAccessor geolocYAccessor; - GDALCachedPixelAccessor backMapXAccessor; - GDALCachedPixelAccessor backMapYAccessor; - GDALCachedPixelAccessor backMapWeightAccessor; + static constexpr int TILE_SIZE = 256; + static constexpr int TILE_COUNT = 64; + + GDALCachedPixelAccessor geolocXAccessor; + GDALCachedPixelAccessor geolocYAccessor; + GDALCachedPixelAccessor backMapXAccessor; + GDALCachedPixelAccessor backMapYAccessor; + GDALCachedPixelAccessor backMapWeightAccessor; explicit GDALGeoLocDatasetAccessors(GDALGeoLocTransformInfo *psTransform) : m_psTransform(psTransform), geolocXAccessor(nullptr), diff --git a/alg/gdalgeolocquadtree.cpp b/alg/gdalgeolocquadtree.cpp index 0276e933f296..8144e8c986e3 100644 --- a/alg/gdalgeolocquadtree.cpp +++ b/alg/gdalgeolocquadtree.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdalgeoloc.h" diff --git a/alg/gdalgeolocquadtree.h b/alg/gdalgeolocquadtree.h index 756d0706100a..73fa99301256 100644 --- a/alg/gdalgeolocquadtree.h +++ b/alg/gdalgeolocquadtree.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2022, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALGEOLOCQUADTREE_H diff --git a/alg/gdalgrid.cpp b/alg/gdalgrid.cpp index 9e46953da70e..044a217e9588 100644 --- a/alg/gdalgrid.cpp +++ b/alg/gdalgrid.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2007, Andrey Kiselev * Copyright (c) 2009-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalgrid.h b/alg/gdalgrid.h index 8dab0e8d397d..6176508c3e42 100644 --- a/alg/gdalgrid.h +++ b/alg/gdalgrid.h @@ -9,23 +9,7 @@ * Copyright (c) 2007, Andrey Kiselev * Copyright (c) 2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALGRID_H_INCLUDED diff --git a/alg/gdalgrid_priv.h b/alg/gdalgrid_priv.h index 3d1a7fc35af6..3c3da523c344 100644 --- a/alg/gdalgrid_priv.h +++ b/alg/gdalgrid_priv.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALGRID_PRIV_H diff --git a/alg/gdalgridavx.cpp b/alg/gdalgridavx.cpp index f198ecb5141e..55c49227f22b 100644 --- a/alg/gdalgridavx.cpp +++ b/alg/gdalgridavx.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdalgrid.h" diff --git a/alg/gdalgridsse.cpp b/alg/gdalgridsse.cpp index 958a5c1033bd..0d5f71f84ce1 100644 --- a/alg/gdalgridsse.cpp +++ b/alg/gdalgridsse.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdalgrid.h" diff --git a/alg/gdallinearsystem.cpp b/alg/gdallinearsystem.cpp index 607e46debccb..c2b8d5241b9f 100644 --- a/alg/gdallinearsystem.cpp +++ b/alg/gdallinearsystem.cpp @@ -12,23 +12,7 @@ * Copyright (c) 2008-2014, Even Rouault * Copyright (c) 2019, Martin Franzke * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /*! @cond Doxygen_Suppress */ diff --git a/alg/gdallinearsystem.h b/alg/gdallinearsystem.h index 23ce47fd7ffe..76e303f6ca77 100644 --- a/alg/gdallinearsystem.h +++ b/alg/gdallinearsystem.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2017 Alan Thomas * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /*! @cond Doxygen_Suppress */ diff --git a/alg/gdalmatching.cpp b/alg/gdalmatching.cpp index 7a78d8beb520..f761bb2c7579 100644 --- a/alg/gdalmatching.cpp +++ b/alg/gdalmatching.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2012, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_alg.h" diff --git a/alg/gdalmediancut.cpp b/alg/gdalmediancut.cpp index 9794c3f153eb..4ffa7931cfb7 100644 --- a/alg/gdalmediancut.cpp +++ b/alg/gdalmediancut.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************** * * This code was based on the tiffmedian.c code from libtiff (www.libtiff.org) diff --git a/alg/gdalpansharpen.cpp b/alg/gdalpansharpen.cpp index a72179071e46..f082b66242fd 100644 --- a/alg/gdalpansharpen.cpp +++ b/alg/gdalpansharpen.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2015, Even Rouault * Copyright (c) 2015, Airbus DS Geo SA (weighted Brovey algorithm) * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -1479,7 +1463,8 @@ CPLErr GDALPansharpenOperation::ProcessRegion(int nXOff, int nYOff, int nXSize, nBandBitDepth = atoi(pszNBITS); if (nBandBitDepth < nBitDepth) { - if (eWorkDataType == GDT_Byte) + if (eWorkDataType == GDT_Byte && nBitDepth >= 0 && + nBitDepth <= 8) { ClampValues( reinterpret_cast(pUpsampledSpectralBuffer) + @@ -1487,7 +1472,8 @@ CPLErr GDALPansharpenOperation::ProcessRegion(int nXOff, int nYOff, int nXSize, static_cast(nXSize) * nYSize, static_cast((1 << nBitDepth) - 1)); } - else if (eWorkDataType == GDT_UInt16) + else if (eWorkDataType == GDT_UInt16 && nBitDepth >= 0 && + nBitDepth <= 16) { ClampValues( reinterpret_cast(pUpsampledSpectralBuffer) + @@ -1508,7 +1494,9 @@ CPLErr GDALPansharpenOperation::ProcessRegion(int nXOff, int nYOff, int nXSize, } } - GUInt32 nMaxValue = (1 << nBitDepth) - 1; + const GUInt32 nMaxValue = (nBitDepth >= 0 && nBitDepth <= 31) + ? (1U << nBitDepth) - 1 + : UINT32_MAX; double *padfTempBuffer = nullptr; GDALDataType eBufDataTypeOri = eBufDataType; diff --git a/alg/gdalpansharpen.h b/alg/gdalpansharpen.h index d9f7582adf3a..d4f1f3102887 100644 --- a/alg/gdalpansharpen.h +++ b/alg/gdalpansharpen.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALPANSHARPEN_H_INCLUDED diff --git a/alg/gdalproximity.cpp b/alg/gdalproximity.cpp index 9f9adf8e97de..aaa9bda10ef8 100644 --- a/alg/gdalproximity.cpp +++ b/alg/gdalproximity.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2008, Frank Warmerdam * Copyright (c) 2009-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalrasterize.cpp b/alg/gdalrasterize.cpp index 6aa6efc998e3..458a8217bf02 100644 --- a/alg/gdalrasterize.cpp +++ b/alg/gdalrasterize.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2005, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalrasterpolygonenumerator.cpp b/alg/gdalrasterpolygonenumerator.cpp index dc9358c41b79..13f7fde8e7fd 100644 --- a/alg/gdalrasterpolygonenumerator.cpp +++ b/alg/gdalrasterpolygonenumerator.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2008, Frank Warmerdam * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalresamplingkernels.h b/alg/gdalresamplingkernels.h index 1a245dca0d3e..9e338834c086 100644 --- a/alg/gdalresamplingkernels.h +++ b/alg/gdalresamplingkernels.h @@ -10,23 +10,7 @@ * Copyright (c) 2008-2012, Even Rouault * Copyright (c) 2024, Javier Jimenez Shaw * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALRESAMPLINGKERNELS_H_INCLUDED diff --git a/alg/gdalsievefilter.cpp b/alg/gdalsievefilter.cpp index 5d11f97105a7..ac9ea1b9e847 100644 --- a/alg/gdalsievefilter.cpp +++ b/alg/gdalsievefilter.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2008, Frank Warmerdam * Copyright (c) 2009-2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalsimplewarp.cpp b/alg/gdalsimplewarp.cpp index 0346068fd6b8..8f4f9a11a9a8 100644 --- a/alg/gdalsimplewarp.cpp +++ b/alg/gdalsimplewarp.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2002, i3 - information integration and imaging, Fort Collin, CO * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdaltransformer.cpp b/alg/gdaltransformer.cpp index 3eda4c75b31c..ba2adc3dc73e 100644 --- a/alg/gdaltransformer.cpp +++ b/alg/gdaltransformer.cpp @@ -11,23 +11,7 @@ * Copyright (c) 2008-2013, Even Rouault * Copyright (c) 2021, CLS * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -885,7 +869,7 @@ CPLErr CPL_STDCALL GDALSuggestedWarpOutput2(GDALDatasetH hSrcDS, "transform.", nFailedCount, nSamplePoints); - bool bIsGeographicCoords = false; + bool bIsGeographicCoordsDeg = false; if (bIsGDALGenImgProjTransform) { const GDALGenImgProjTransformInfo *pGIPTI = @@ -915,15 +899,17 @@ CPLErr CPL_STDCALL GDALSuggestedWarpOutput2(GDALDatasetH hSrcDS, CSLFetchNameValue(pGLTI->papszGeolocationInfo, "SRS"); if (pszGLSRS == nullptr) { - bIsGeographicCoords = true; + bIsGeographicCoordsDeg = true; } else { OGRSpatialReference oSRS; if (oSRS.SetFromUserInput(pszGLSRS) == OGRERR_NONE && - oSRS.IsGeographic()) + oSRS.IsGeographic() && + std::fabs(oSRS.GetAngularUnits() - + CPLAtof(SRS_UA_DEGREE_CONV)) < 1e-9) { - bIsGeographicCoords = true; + bIsGeographicCoordsDeg = true; } } } @@ -983,7 +969,7 @@ CPLErr CPL_STDCALL GDALSuggestedWarpOutput2(GDALDatasetH hSrcDS, CPLAtof(SRS_UA_DEGREE_CONV)) < 1e-9 && (!poSourceCRS || !poSourceCRS->IsGeographic())) { - bIsGeographicCoords = true; + bIsGeographicCoordsDeg = true; std::unique_ptr poSetter; if (pGIPTI->bCheckWithInvertPROJ) @@ -1210,7 +1196,7 @@ CPLErr CPL_STDCALL GDALSuggestedWarpOutput2(GDALDatasetH hSrcDS, /* Recompute some bounds so that all return values are consistent */ /* -------------------------------------------------------------------- */ double dfMaxXOutNew = dfMinXOut + (*pnPixels) * dfPixelSizeX; - if (bIsGeographicCoords && + if (bIsGeographicCoordsDeg && ((dfMaxXOut <= 180 && dfMaxXOutNew > 180) || dfMaxXOut == 180)) { dfMaxXOut = 180; @@ -1222,7 +1208,7 @@ CPLErr CPL_STDCALL GDALSuggestedWarpOutput2(GDALDatasetH hSrcDS, } double dfMinYOutNew = dfMaxYOut - (*pnLines) * dfPixelSizeY; - if (bIsGeographicCoords && dfMinYOut >= -90 && dfMinYOutNew < -90) + if (bIsGeographicCoordsDeg && dfMinYOut >= -90 && dfMinYOutNew < -90) { dfMinYOut = -90; dfPixelSizeY = (dfMaxYOut - dfMinYOut) / *pnLines; @@ -1442,8 +1428,11 @@ static void InsertCenterLong(GDALDatasetH hDS, OGRSpatialReference *poSRS, CPLStringList &aosOptions) { - if (!poSRS->IsGeographic()) + if (!poSRS->IsGeographic() || std::fabs(poSRS->GetAngularUnits() - + CPLAtof(SRS_UA_DEGREE_CONV)) > 1e-9) + { return; + } if (poSRS->GetExtension(nullptr, "CENTER_LONG")) return; @@ -2983,7 +2972,9 @@ int GDALTransformLonLatToDestGenImgProjTransformer(void *hTransformArg, double z = 0; int success = true; auto poSourceCRS = psReprojInfo->poForwardTransform->GetSourceCS(); - if (poSourceCRS->IsGeographic()) + if (poSourceCRS->IsGeographic() && + std::fabs(poSourceCRS->GetAngularUnits() - + CPLAtof(SRS_UA_DEGREE_CONV)) < 1e-9) { // Optimization to avoid creating a OGRCoordinateTransformation OGRAxisOrientation eSourceFirstAxisOrient = OAO_Other; @@ -4919,3 +4910,42 @@ bool GDALTransformIsAffineNoRotation(GDALTransformerFunc, void *pTransformerArg) } return false; } + +/************************************************************************/ +/* GDALTransformHasFastClone() */ +/************************************************************************/ + +/** Returns whether GDALCloneTransformer() on this transformer is + * "fast" + * Counter-examples are GCPs or TPSs transformers. + */ +bool GDALTransformHasFastClone(void *pTransformerArg) +{ + if (GDALIsTransformer(pTransformerArg, GDAL_APPROX_TRANSFORMER_CLASS_NAME)) + { + const auto *pApproxInfo = + static_cast(pTransformerArg); + pTransformerArg = pApproxInfo->pBaseCBData; + // Fallback to next lines + } + + if (GDALIsTransformer(pTransformerArg, GDAL_GEN_IMG_TRANSFORMER_CLASS_NAME)) + { + const auto *pGenImgpProjInfo = + static_cast(pTransformerArg); + return (pGenImgpProjInfo->pSrcTransformArg == nullptr || + GDALTransformHasFastClone( + pGenImgpProjInfo->pSrcTransformArg)) && + (pGenImgpProjInfo->pDstTransformArg == nullptr || + GDALTransformHasFastClone(pGenImgpProjInfo->pDstTransformArg)); + } + else if (GDALIsTransformer(pTransformerArg, + GDAL_RPC_TRANSFORMER_CLASS_NAME)) + { + return true; + } + else + { + return false; + } +} diff --git a/alg/gdaltransformgeolocs.cpp b/alg/gdaltransformgeolocs.cpp index 7d53d01b6503..e7283f5c90db 100644 --- a/alg/gdaltransformgeolocs.cpp +++ b/alg/gdaltransformgeolocs.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2012, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/gdalwarper.cpp b/alg/gdalwarper.cpp index ca78650897b3..b07664bf1eec 100644 --- a/alg/gdalwarper.cpp +++ b/alg/gdalwarper.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2008-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -1167,6 +1151,20 @@ CPLErr GDALWarpDstAlphaMasker(void *pMaskFuncArg, int nBandCount, * will be selected, not just those whose center point falls within the * polygon. * + *
  • XSCALE: Ratio expressing the resampling factor (number of destination + * pixels per source pixel) along the target horizontal axis. + * The scale is used to determine the number of source pixels along the x-axis + * that are considered by the resampling algorithm. + * Equals to one for no resampling, below one for downsampling + * and above one for upsampling. This is automatically computed, for each + * processing chunk, and may thus vary among them, depending on the + * shape of output regions vs input regions. Such variations can be undesired + * in some situations. If the resampling factor can be considered as constant + * over the warped area, setting a constant value can lead to more reproducible + * pixel output.
  • + * + *
  • YSCALE: Same as XSCALE, but along the horizontal axis.
  • + * *
  • OPTIMIZE_SIZE: This defaults to FALSE, but may be set to TRUE * typically when writing to a compressed dataset (GeoTIFF with * COMPRESS creation option set for example) for achieving a smaller @@ -1176,7 +1174,11 @@ CPLErr GDALWarpDstAlphaMasker(void *pMaskFuncArg, int nBandCount, * of the file. However sticking to target block size may cause major * processing slowdown for some particular reprojections. Starting * with GDAL 3.8, OPTIMIZE_SIZE mode is automatically enabled when it is safe - * to do so.
  • + * to do so. + * As this parameter influences the shape of warping chunk, and by default the + * XSCALE and YSCALE parameters are computed per warping chunk, this parameter may + * influence the pixel output. + * * *
  • NUM_THREADS: (GDAL >= 1.10) Can be set to a numeric value or ALL_CPUS to * set the number of threads to use to parallelize the computation part of the diff --git a/alg/gdalwarper.h b/alg/gdalwarper.h index 90ca632a091b..010fec7afb5f 100644 --- a/alg/gdalwarper.h +++ b/alg/gdalwarper.h @@ -9,23 +9,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2009-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALWARPER_H_INCLUDED @@ -557,6 +541,9 @@ class CPL_DLL GDALWarpOperation CPLErr Initialize(const GDALWarpOptions *psNewOptions); void *CreateDestinationBuffer(int nDstXSize, int nDstYSize, int *pbWasInitialized = nullptr); + void InitializeDestinationBuffer(void *pDstBuffer, int nDstXSize, + int nDstYSize, + int *pbWasInitialized = nullptr); static void DestroyDestinationBuffer(void *pDstBuffer); const GDALWarpOptions *GetOptions(); diff --git a/alg/gdalwarpkernel.cpp b/alg/gdalwarpkernel.cpp index 2c046b67f055..9d475d0dd79d 100644 --- a/alg/gdalwarpkernel.cpp +++ b/alg/gdalwarpkernel.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -2865,11 +2849,14 @@ static bool GWKBilinearResampleNoMasks4SampleT(const GDALWarpKernel *poWK, // or http://en.wikipedia.org/wiki/Cubic_Hermite_spline : CINTx(p_1,p0,p1,p2) // http://en.wikipedia.org/wiki/Bicubic_interpolation: matrix notation -// TODO(schwehr): Use an inline function. -#define CubicConvolution(distance1, distance2, distance3, f0, f1, f2, f3) \ - (f1 + 0.5 * (distance1 * (f2 - f0) + \ - distance2 * (2.0 * f0 - 5.0 * f1 + 4.0 * f2 - f3) + \ - distance3 * (3.0 * (f1 - f2) + f3 - f0))) +template +static inline T CubicConvolution(T distance1, T distance2, T distance3, T f0, + T f1, T f2, T f3) +{ + return (f1 + T(0.5) * (distance1 * (f2 - f0) + + distance2 * (2 * f0 - 5 * f1 + 4 * f2 - f3) + + distance3 * (3 * (f1 - f2) + f3 - f0))); +} /************************************************************************/ /* GWKCubicComputeWeights() */ @@ -2877,19 +2864,18 @@ static bool GWKBilinearResampleNoMasks4SampleT(const GDALWarpKernel *poWK, // adfCoeffs[2] = 1.0 - (adfCoeffs[0] + adfCoeffs[1] - adfCoeffs[3]); -// TODO(schwehr): Use an inline function. -#define GWKCubicComputeWeights(dfX_, adfCoeffs) \ - { \ - const double dfX = dfX_; \ - const double dfHalfX = 0.5 * dfX; \ - const double dfThreeX = 3.0 * dfX; \ - const double dfHalfX2 = dfHalfX * dfX; \ - \ - adfCoeffs[0] = dfHalfX * (-1 + dfX * (2 - dfX)); \ - adfCoeffs[1] = 1 + dfHalfX2 * (-5 + dfThreeX); \ - adfCoeffs[2] = dfHalfX * (1 + dfX * (4 - dfThreeX)); \ - adfCoeffs[3] = dfHalfX2 * (-1 + dfX); \ - } +template +static inline void GWKCubicComputeWeights(T x, T coeffs[4]) +{ + const T halfX = T(0.5) * x; + const T threeX = T(3.0) * x; + const T halfX2 = halfX * x; + + coeffs[0] = halfX * (-1 + x * (2 - x)); + coeffs[1] = 1 + halfX2 * (-5 + threeX); + coeffs[2] = halfX * (1 + x * (4 - threeX)); + coeffs[3] = halfX2 * (-1 + x); +} // TODO(schwehr): Use an inline function. #define CONVOL4(v1, v2) \ @@ -2985,10 +2971,7 @@ static bool GWKCubicResample4Sample(const GDALWarpKernel *poWK, int iBand, return true; } -// We do not define USE_SSE_CUBIC_IMPL since in practice, it gives zero -// perf benefit. - -#if defined(USE_SSE_CUBIC_IMPL) && (defined(__x86_64) || defined(_M_X64)) +#if defined(__x86_64) || defined(_M_X64) /************************************************************************/ /* XMMLoad4Values() */ @@ -3001,7 +2984,7 @@ static CPL_INLINE __m128 XMMLoad4Values(const GByte *ptr) { unsigned int i; memcpy(&i, ptr, 4); - __m128i xmm_i = _mm_cvtsi32_si128(s); + __m128i xmm_i = _mm_cvtsi32_si128(i); // Zero extend 4 packed unsigned 8-bit integers in a to packed // 32-bit integers. #if __SSE4_1__ @@ -3017,7 +3000,7 @@ static CPL_INLINE __m128 XMMLoad4Values(const GUInt16 *ptr) { GUInt64 i; memcpy(&i, ptr, 8); - __m128i xmm_i = _mm_cvtsi64_si128(s); + __m128i xmm_i = _mm_cvtsi64_si128(i); // Zero extend 4 packed unsigned 16-bit integers in a to packed // 32-bit integers. #if __SSE4_1__ @@ -3054,7 +3037,7 @@ static CPL_INLINE float XMMHorizontalAdd(__m128 v) } #endif -#endif // defined(USE_SSE_CUBIC_IMPL) && (defined(__x86_64) || defined(_M_X64)) +#endif // (defined(__x86_64) || defined(_M_X64)) /************************************************************************/ /* GWKCubicResampleSrcMaskIsDensity4SampleRealT() */ @@ -3062,6 +3045,8 @@ static CPL_INLINE float XMMHorizontalAdd(__m128 v) // Note: if USE_SSE_CUBIC_IMPL, only instantiate that for Byte and UInt16, // because there are a few assumptions above those types. +// We do not define USE_SSE_CUBIC_IMPL since in practice, it gives zero +// perf benefit. template static CPL_INLINE bool GWKCubicResampleSrcMaskIsDensity4SampleRealT( @@ -3325,7 +3310,13 @@ static double GWKLanczosSinc(double dfX) const double dfPIX = M_PI * dfX; const double dfPIXoverR = dfPIX / 3; const double dfPIX2overR = dfPIX * dfPIXoverR; - return sin(dfPIX) * sin(dfPIXoverR) / dfPIX2overR; + // Given that sin(3x) = 3 sin(x) - 4 sin^3 (x) + // we can compute sin(dfSinPIX) from sin(dfPIXoverR) + const double dfSinPIXoverR = sin(dfPIXoverR); + const double dfSinPIXoverRSquared = dfSinPIXoverR * dfSinPIXoverR; + const double dfSinPIXMulSinPIXoverR = + (3 - 4 * dfSinPIXoverRSquared) * dfSinPIXoverRSquared; + return dfSinPIXMulSinPIXoverR / dfPIX2overR; } static double GWKLanczosSinc4Values(double *padfValues) @@ -3341,7 +3332,13 @@ static double GWKLanczosSinc4Values(double *padfValues) const double dfPIX = M_PI * padfValues[i]; const double dfPIXoverR = dfPIX / 3; const double dfPIX2overR = dfPIX * dfPIXoverR; - padfValues[i] = sin(dfPIX) * sin(dfPIXoverR) / dfPIX2overR; + // Given that sin(3x) = 3 sin(x) - 4 sin^3 (x) + // we can compute sin(dfSinPIX) from sin(dfPIXoverR) + const double dfSinPIXoverR = sin(dfPIXoverR); + const double dfSinPIXoverRSquared = dfSinPIXoverR * dfSinPIXoverR; + const double dfSinPIXMulSinPIXoverR = + (3 - 4 * dfSinPIXoverRSquared) * dfSinPIXoverRSquared; + padfValues[i] = dfSinPIXMulSinPIXoverR / dfPIX2overR; } } return padfValues[0] + padfValues[1] + padfValues[2] + padfValues[3]; @@ -3518,11 +3515,19 @@ struct _GWKResampleWrkStruct double *padfWeightsX; bool *pabCalcX; - double *padfWeightsY; // Only used by GWKResampleOptimizedLanczos. - int iLastSrcX; // Only used by GWKResampleOptimizedLanczos. - int iLastSrcY; // Only used by GWKResampleOptimizedLanczos. - double dfLastDeltaX; // Only used by GWKResampleOptimizedLanczos. - double dfLastDeltaY; // Only used by GWKResampleOptimizedLanczos. + double *padfWeightsY; // Only used by GWKResampleOptimizedLanczos. + int iLastSrcX; // Only used by GWKResampleOptimizedLanczos. + int iLastSrcY; // Only used by GWKResampleOptimizedLanczos. + double dfLastDeltaX; // Only used by GWKResampleOptimizedLanczos. + double dfLastDeltaY; // Only used by GWKResampleOptimizedLanczos. + double dfCosPiXScale; // Only used by GWKResampleOptimizedLanczos. + double dfSinPiXScale; // Only used by GWKResampleOptimizedLanczos. + double dfCosPiXScaleOver3; // Only used by GWKResampleOptimizedLanczos. + double dfSinPiXScaleOver3; // Only used by GWKResampleOptimizedLanczos. + double dfCosPiYScale; // Only used by GWKResampleOptimizedLanczos. + double dfSinPiYScale; // Only used by GWKResampleOptimizedLanczos. + double dfCosPiYScaleOver3; // Only used by GWKResampleOptimizedLanczos. + double dfSinPiYScaleOver3; // Only used by GWKResampleOptimizedLanczos. // Space for saving a row of pixels. double *padfRowDensity; @@ -3550,7 +3555,7 @@ static GWKResampleWrkStruct *GWKResampleCreateWrkStruct(GDALWarpKernel *poWK) const int nYDist = (poWK->nYRadius + 1) * 2; GWKResampleWrkStruct *psWrkStruct = static_cast( - CPLMalloc(sizeof(GWKResampleWrkStruct))); + CPLCalloc(1, sizeof(GWKResampleWrkStruct))); // Alloc space for saved X weights. psWrkStruct->padfWeightsX = @@ -3586,38 +3591,40 @@ static GWKResampleWrkStruct *GWKResampleCreateWrkStruct(GDALWarpKernel *poWK) { psWrkStruct->pfnGWKResample = GWKResampleOptimizedLanczos; - const double dfXScale = poWK->dfXScale; - if (dfXScale < 1.0) + if (poWK->dfXScale < 1) { - int iMin = poWK->nFiltInitX; - int iMax = poWK->nXRadius; - while (iMin * dfXScale < -3.0) - iMin++; - while (iMax * dfXScale > 3.0) - iMax--; - - for (int i = iMin; i <= iMax; ++i) - { - psWrkStruct->padfWeightsX[i - poWK->nFiltInitX] = - GWKLanczosSinc(i * dfXScale); - } + psWrkStruct->dfCosPiXScaleOver3 = cos(M_PI / 3 * poWK->dfXScale); + psWrkStruct->dfSinPiXScaleOver3 = + sqrt(1 - psWrkStruct->dfCosPiXScaleOver3 * + psWrkStruct->dfCosPiXScaleOver3); + // "Naive": + // const double dfCosPiXScale = cos( M_PI * dfXScale ); + // const double dfSinPiXScale = sin( M_PI * dfXScale ); + // but given that cos(3x) = 4 cos^3(x) - 3 cos(x) and x between 0 and M_PI + psWrkStruct->dfCosPiXScale = (4 * psWrkStruct->dfCosPiXScaleOver3 * + psWrkStruct->dfCosPiXScaleOver3 - + 3) * + psWrkStruct->dfCosPiXScaleOver3; + psWrkStruct->dfSinPiXScale = sqrt( + 1 - psWrkStruct->dfCosPiXScale * psWrkStruct->dfCosPiXScale); } - const double dfYScale = poWK->dfYScale; - if (dfYScale < 1.0) + if (poWK->dfYScale < 1) { - int jMin = poWK->nFiltInitY; - int jMax = poWK->nYRadius; - while (jMin * dfYScale < -3.0) - jMin++; - while (jMax * dfYScale > 3.0) - jMax--; - - for (int j = jMin; j <= jMax; ++j) - { - psWrkStruct->padfWeightsY[j - poWK->nFiltInitY] = - GWKLanczosSinc(j * dfYScale); - } + psWrkStruct->dfCosPiYScaleOver3 = cos(M_PI / 3 * poWK->dfYScale); + psWrkStruct->dfSinPiYScaleOver3 = + sqrt(1 - psWrkStruct->dfCosPiYScaleOver3 * + psWrkStruct->dfCosPiYScaleOver3); + // "Naive": + // const double dfCosPiYScale = cos( M_PI * dfYScale ); + // const double dfSinPiYScale = sin( M_PI * dfYScale ); + // but given that cos(3x) = 4 cos^3(x) - 3 cos(x) and x between 0 and M_PI + psWrkStruct->dfCosPiYScale = (4 * psWrkStruct->dfCosPiYScaleOver3 * + psWrkStruct->dfCosPiYScaleOver3 - + 3) * + psWrkStruct->dfCosPiYScaleOver3; + psWrkStruct->dfSinPiYScale = sqrt( + 1 - psWrkStruct->dfCosPiYScale * psWrkStruct->dfCosPiYScale); } } else @@ -3832,13 +3839,15 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, const double dfYScale = poWK->dfYScale; // Space for saved X weights. - double *padfWeightsX = psWrkStruct->padfWeightsX; - double *padfWeightsY = psWrkStruct->padfWeightsY; + double *const padfWeightsXShifted = + psWrkStruct->padfWeightsX - poWK->nFiltInitX; + double *const padfWeightsYShifted = + psWrkStruct->padfWeightsY - poWK->nFiltInitY; // Space for saving a row of pixels. - double *padfRowDensity = psWrkStruct->padfRowDensity; - double *padfRowReal = psWrkStruct->padfRowReal; - double *padfRowImag = psWrkStruct->padfRowImag; + double *const padfRowDensity = psWrkStruct->padfRowDensity; + double *const padfRowReal = psWrkStruct->padfRowReal; + double *const padfRowImag = psWrkStruct->padfRowImag; // Skip sampling over edge of image. int jMin = poWK->nFiltInitY; @@ -3857,11 +3866,86 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, if (dfXScale < 1.0) { - while (iMin * dfXScale < -3.0) + while ((iMin - dfDeltaX) * dfXScale < -3.0) iMin++; - while (iMax * dfXScale > 3.0) + while ((iMax - dfDeltaX) * dfXScale > 3.0) iMax--; - // padfWeightsX computed in GWKResampleCreateWrkStruct. + + // clang-format off + /* + Naive version: + for (int i = iMin; i <= iMax; ++i) + { + psWrkStruct->padfWeightsXShifted[i] = + GWKLanczosSinc((i - dfDeltaX) * dfXScale); + } + + but given that: + + GWKLanczosSinc(x): + if (dfX == 0.0) + return 1.0; + + const double dfPIX = M_PI * dfX; + const double dfPIXoverR = dfPIX / 3; + const double dfPIX2overR = dfPIX * dfPIXoverR; + return sin(dfPIX) * sin(dfPIXoverR) / dfPIX2overR; + + and + sin (a + b) = sin a cos b + cos a sin b. + cos (a + b) = cos a cos b - sin a sin b. + + we can skip any sin() computation within the loop + */ + // clang-format on + + if (iSrcX != psWrkStruct->iLastSrcX || + dfDeltaX != psWrkStruct->dfLastDeltaX) + { + double dfX = (iMin - dfDeltaX) * dfXScale; + + double dfPIXover3 = M_PI / 3 * dfX; + double dfCosOver3 = cos(dfPIXover3); + double dfSinOver3 = sin(dfPIXover3); + + // "Naive": + // double dfSin = sin( M_PI * dfX ); + // double dfCos = cos( M_PI * dfX ); + // but given that cos(3x) = 4 cos^3(x) - 3 cos(x) and sin(3x) = 3 sin(x) - 4 sin^3 (x). + double dfSin = (3 - 4 * dfSinOver3 * dfSinOver3) * dfSinOver3; + double dfCos = (4 * dfCosOver3 * dfCosOver3 - 3) * dfCosOver3; + + const double dfCosPiXScaleOver3 = psWrkStruct->dfCosPiXScaleOver3; + const double dfSinPiXScaleOver3 = psWrkStruct->dfSinPiXScaleOver3; + const double dfCosPiXScale = psWrkStruct->dfCosPiXScale; + const double dfSinPiXScale = psWrkStruct->dfSinPiXScale; + constexpr double THREE_PI_PI = 3 * M_PI * M_PI; + padfWeightsXShifted[iMin] = + dfX == 0 ? 1.0 : THREE_PI_PI * dfSin * dfSinOver3 / (dfX * dfX); + for (int i = iMin + 1; i <= iMax; ++i) + { + dfX += dfXScale; + const double dfNewSin = + dfSin * dfCosPiXScale + dfCos * dfSinPiXScale; + const double dfNewSinOver3 = dfSinOver3 * dfCosPiXScaleOver3 + + dfCosOver3 * dfSinPiXScaleOver3; + padfWeightsXShifted[i] = + dfX == 0 + ? 1.0 + : THREE_PI_PI * dfNewSin * dfNewSinOver3 / (dfX * dfX); + const double dfNewCos = + dfCos * dfCosPiXScale - dfSin * dfSinPiXScale; + const double dfNewCosOver3 = dfCosOver3 * dfCosPiXScaleOver3 - + dfSinOver3 * dfSinPiXScaleOver3; + dfSin = dfNewSin; + dfCos = dfNewCos; + dfSinOver3 = dfNewSinOver3; + dfCosOver3 = dfNewCosOver3; + } + + psWrkStruct->iLastSrcX = iSrcX; + psWrkStruct->dfLastDeltaX = dfDeltaX; + } } else { @@ -3877,17 +3961,18 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, // following trigonometric formulas. // TODO(schwehr): Move this somewhere where it can be rendered at - // LaTeX. sin(M_PI * (dfBase + k)) = sin(M_PI * dfBase) * cos(M_PI * - // k) + cos(M_PI * dfBase) * sin(M_PI * k) sin(M_PI * (dfBase + k)) - // = dfSinPIBase * cos(M_PI * k) + dfCosPIBase * sin(M_PI * k) + // LaTeX. + // clang-format off + // sin(M_PI * (dfBase + k)) = sin(M_PI * dfBase) * cos(M_PI * k) + + // cos(M_PI * dfBase) * sin(M_PI * k) + // sin(M_PI * (dfBase + k)) = dfSinPIBase * cos(M_PI * k) + dfCosPIBase * sin(M_PI * k) // sin(M_PI * (dfBase + k)) = dfSinPIBase * cos(M_PI * k) - // sin(M_PI * (dfBase + k)) = dfSinPIBase * (((k % 2) == 0) ? 1 : - // -1) + // sin(M_PI * (dfBase + k)) = dfSinPIBase * (((k % 2) == 0) ? 1 : -1) - // sin(M_PI / dfR * (dfBase + k)) = sin(M_PI / dfR * dfBase) * - // cos(M_PI / dfR * k) + cos(M_PI / dfR * dfBase) * sin(M_PI / dfR * - // k) sin(M_PI / dfR * (dfBase + k)) = dfSinPIBaseOverR * cos(M_PI / - // dfR * k) + dfCosPIBaseOverR * sin(M_PI / dfR * k) + // sin(M_PI / dfR * (dfBase + k)) = sin(M_PI / dfR * dfBase) * cos(M_PI / dfR * k) + + // cos(M_PI / dfR * dfBase) * sin(M_PI / dfR * k) + // sin(M_PI / dfR * (dfBase + k)) = dfSinPIBaseOverR * cos(M_PI / dfR * k) + dfCosPIBaseOverR * sin(M_PI / dfR * k) + // clang-format on const double dfSinPIDeltaXOver3 = sin((-M_PI / 3.0) * dfDeltaX); const double dfSin2PIDeltaXOver3 = @@ -3915,10 +4000,9 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, { const double dfX = i - dfDeltaX; if (dfX == 0.0) - padfWeightsX[i - poWK->nFiltInitX] = 1.0; + padfWeightsXShifted[i] = 1.0; else - padfWeightsX[i - poWK->nFiltInitX] = - padfCst[(i + 3) % 3] / (dfX * dfX); + padfWeightsXShifted[i] = padfCst[(i + 3) % 3] / (dfX * dfX); #if DEBUG_VERBOSE // TODO(schwehr): AlmostEqual. // CPLAssert(fabs(padfWeightsX[i-poWK->nFiltInitX] - @@ -3933,11 +4017,69 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, if (dfYScale < 1.0) { - while (jMin * dfYScale < -3.0) + while ((jMin - dfDeltaY) * dfYScale < -3.0) jMin++; - while (jMax * dfYScale > 3.0) + while ((jMax - dfDeltaY) * dfYScale > 3.0) jMax--; - // padfWeightsY computed in GWKResampleCreateWrkStruct. + + // clang-format off + /* + Naive version: + for (int j = jMin; j <= jMax; ++j) + { + padfWeightsYShifted[j] = + GWKLanczosSinc((j - dfDeltaY) * dfYScale); + } + */ + // clang-format on + + if (iSrcY != psWrkStruct->iLastSrcY || + dfDeltaY != psWrkStruct->dfLastDeltaY) + { + double dfY = (jMin - dfDeltaY) * dfYScale; + + double dfPIYover3 = M_PI / 3 * dfY; + double dfCosOver3 = cos(dfPIYover3); + double dfSinOver3 = sin(dfPIYover3); + + // "Naive": + // double dfSin = sin( M_PI * dfY ); + // double dfCos = cos( M_PI * dfY ); + // but given that cos(3x) = 4 cos^3(x) - 3 cos(x) and sin(3x) = 3 sin(x) - 4 sin^3 (x). + double dfSin = (3 - 4 * dfSinOver3 * dfSinOver3) * dfSinOver3; + double dfCos = (4 * dfCosOver3 * dfCosOver3 - 3) * dfCosOver3; + + const double dfCosPiYScaleOver3 = psWrkStruct->dfCosPiYScaleOver3; + const double dfSinPiYScaleOver3 = psWrkStruct->dfSinPiYScaleOver3; + const double dfCosPiYScale = psWrkStruct->dfCosPiYScale; + const double dfSinPiYScale = psWrkStruct->dfSinPiYScale; + constexpr double THREE_PI_PI = 3 * M_PI * M_PI; + padfWeightsYShifted[jMin] = + dfY == 0 ? 1.0 : THREE_PI_PI * dfSin * dfSinOver3 / (dfY * dfY); + for (int j = jMin + 1; j <= jMax; ++j) + { + dfY += dfYScale; + const double dfNewSin = + dfSin * dfCosPiYScale + dfCos * dfSinPiYScale; + const double dfNewSinOver3 = dfSinOver3 * dfCosPiYScaleOver3 + + dfCosOver3 * dfSinPiYScaleOver3; + padfWeightsYShifted[j] = + dfY == 0 + ? 1.0 + : THREE_PI_PI * dfNewSin * dfNewSinOver3 / (dfY * dfY); + const double dfNewCos = + dfCos * dfCosPiYScale - dfSin * dfSinPiYScale; + const double dfNewCosOver3 = dfCosOver3 * dfCosPiYScaleOver3 - + dfSinOver3 * dfSinPiYScaleOver3; + dfSin = dfNewSin; + dfCos = dfNewCos; + dfSinOver3 = dfNewSinOver3; + dfCosOver3 = dfNewCosOver3; + } + + psWrkStruct->iLastSrcY = iSrcY; + psWrkStruct->dfLastDeltaY = dfDeltaY; + } } else { @@ -3975,13 +4117,12 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, { const double dfY = j - dfDeltaY; if (dfY == 0.0) - padfWeightsY[j - poWK->nFiltInitY] = 1.0; + padfWeightsYShifted[j] = 1.0; else - padfWeightsY[j - poWK->nFiltInitY] = - padfCst[(j + 3) % 3] / (dfY * dfY); + padfWeightsYShifted[j] = padfCst[(j + 3) % 3] / (dfY * dfY); #if DEBUG_VERBOSE // TODO(schwehr): AlmostEqual. - // CPLAssert(fabs(padfWeightsY[j-poWK->nFiltInitY] - + // CPLAssert(fabs(padfWeightsYShifted[j] - // GWKLanczosSinc(dfY, 3.0)) < 1e-10); #endif } @@ -3991,9 +4132,6 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, } } - GPtrDiff_t iRowOffset = - iSrcOffset + static_cast(jMin - 1) * nSrcXSize + iMin; - // If we have no density information, we can simply compute the // accumulated weight. if (padfRowDensity == nullptr) @@ -4001,20 +4139,128 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, double dfRowAccWeight = 0.0; for (int i = iMin; i <= iMax; ++i) { - dfRowAccWeight += padfWeightsX[i - poWK->nFiltInitX]; + dfRowAccWeight += padfWeightsXShifted[i]; } double dfColAccWeight = 0.0; for (int j = jMin; j <= jMax; ++j) { - dfColAccWeight += padfWeightsY[j - poWK->nFiltInitY]; + dfColAccWeight += padfWeightsYShifted[j]; } dfAccumulatorWeight = dfRowAccWeight * dfColAccWeight; } - const bool bIsNonComplex = !GDALDataTypeIsComplex(poWK->eWorkingDataType); - // Loop over pixel rows in the kernel. + + if (poWK->eWorkingDataType == GDT_Byte && !poWK->panUnifiedSrcValid && + !poWK->papanBandSrcValid && !poWK->pafUnifiedSrcDensity && + !padfRowDensity) + { + // Optimization for Byte case without any masking/alpha + + if (dfAccumulatorWeight < 0.000001) + { + *pdfDensity = 0.0; + return false; + } + + const GByte *pSrc = + reinterpret_cast(poWK->papabySrcImage[iBand]); + pSrc += iSrcOffset + static_cast(jMin) * nSrcXSize; + +#if defined(__x86_64) || defined(_M_X64) + if (iMax - iMin + 1 == 6) + { + // This is just an optimized version of the general case in + // the else clause. + + pSrc += iMin; + int j = jMin; + const auto fourXWeights = + XMMReg4Double::Load4Val(padfWeightsXShifted + iMin); + + // Process 2 lines at the same time. + for (; j < jMax; j += 2) + { + const XMMReg4Double v_acc = + XMMReg4Double::Load4Val(pSrc) * fourXWeights; + const XMMReg4Double v_acc2 = + XMMReg4Double::Load4Val(pSrc + nSrcXSize) * fourXWeights; + const double dfRowAcc = v_acc.GetHorizSum(); + const double dfRowAccEnd = + pSrc[4] * padfWeightsXShifted[iMin + 4] + + pSrc[5] * padfWeightsXShifted[iMin + 5]; + dfAccumulatorReal += + (dfRowAcc + dfRowAccEnd) * padfWeightsYShifted[j]; + const double dfRowAcc2 = v_acc2.GetHorizSum(); + const double dfRowAcc2End = + pSrc[nSrcXSize + 4] * padfWeightsXShifted[iMin + 4] + + pSrc[nSrcXSize + 5] * padfWeightsXShifted[iMin + 5]; + dfAccumulatorReal += + (dfRowAcc2 + dfRowAcc2End) * padfWeightsYShifted[j + 1]; + pSrc += 2 * nSrcXSize; + } + if (j == jMax) + { + // Process last line if there's an odd number of them. + + const XMMReg4Double v_acc = + XMMReg4Double::Load4Val(pSrc) * fourXWeights; + const double dfRowAcc = v_acc.GetHorizSum(); + const double dfRowAccEnd = + pSrc[4] * padfWeightsXShifted[iMin + 4] + + pSrc[5] * padfWeightsXShifted[iMin + 5]; + dfAccumulatorReal += + (dfRowAcc + dfRowAccEnd) * padfWeightsYShifted[j]; + } + } + else +#endif + { + for (int j = jMin; j <= jMax; ++j) + { + int i = iMin; + double dfRowAcc1 = 0.0; + double dfRowAcc2 = 0.0; + // A bit of loop unrolling + for (; i < iMax; i += 2) + { + dfRowAcc1 += pSrc[i] * padfWeightsXShifted[i]; + dfRowAcc2 += pSrc[i + 1] * padfWeightsXShifted[i + 1]; + } + if (i == iMax) + { + // Process last column if there's an odd number of them. + dfRowAcc1 += pSrc[i] * padfWeightsXShifted[i]; + } + + dfAccumulatorReal += + (dfRowAcc1 + dfRowAcc2) * padfWeightsYShifted[j]; + pSrc += nSrcXSize; + } + } + + // Calculate the output taking into account weighting. + if (dfAccumulatorWeight < 0.99999 || dfAccumulatorWeight > 1.00001) + { + const double dfInvAcc = 1.0 / dfAccumulatorWeight; + *pdfReal = dfAccumulatorReal * dfInvAcc; + *pdfDensity = 1.0; + } + else + { + *pdfReal = dfAccumulatorReal; + *pdfDensity = 1.0; + } + + return true; + } + + GPtrDiff_t iRowOffset = + iSrcOffset + static_cast(jMin - 1) * nSrcXSize + iMin; + int nCountValid = 0; + const bool bIsNonComplex = !GDALDataTypeIsComplex(poWK->eWorkingDataType); + for (int j = jMin; j <= jMax; ++j) { iRowOffset += nSrcXSize; @@ -4028,7 +4274,7 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, padfRowDensity, padfRowReal, padfRowImag)) continue; - const double dfWeight1 = padfWeightsY[j - poWK->nFiltInitY]; + const double dfWeight1 = padfWeightsYShifted[j]; // Iterate over pixels in row. if (padfRowDensity != nullptr) @@ -4042,8 +4288,7 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, nCountValid++; // Use a cached set of weights for this row. - const double dfWeight2 = - dfWeight1 * padfWeightsX[i - poWK->nFiltInitX]; + const double dfWeight2 = dfWeight1 * padfWeightsXShifted[i]; // Accumulate! dfAccumulatorReal += padfRowReal[i - iMin] * dfWeight2; @@ -4057,7 +4302,7 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, double dfRowAccReal = 0.0; for (int i = iMin; i <= iMax; ++i) { - const double dfWeight2 = padfWeightsX[i - poWK->nFiltInitX]; + const double dfWeight2 = padfWeightsXShifted[i]; // Accumulate! dfRowAccReal += padfRowReal[i - iMin] * dfWeight2; @@ -4071,7 +4316,7 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, double dfRowAccImag = 0.0; for (int i = iMin; i <= iMax; ++i) { - const double dfWeight2 = padfWeightsX[i - poWK->nFiltInitX]; + const double dfWeight2 = padfWeightsXShifted[i]; // Accumulate! dfRowAccReal += padfRowReal[i - iMin] * dfWeight2; @@ -4116,14 +4361,76 @@ static bool GWKResampleOptimizedLanczos(const GDALWarpKernel *poWK, int iBand, return true; } +/************************************************************************/ +/* GWKComputeWeights() */ +/************************************************************************/ + +static void GWKComputeWeights(GDALResampleAlg eResample, int iMin, int iMax, + double dfDeltaX, double dfXScale, int jMin, + int jMax, double dfDeltaY, double dfYScale, + double *padfWeightsHorizontal, + double *padfWeightsVertical, double &dfInvWeights) +{ + + const FilterFuncType pfnGetWeight = apfGWKFilter[eResample]; + CPLAssert(pfnGetWeight); + const FilterFunc4ValuesType pfnGetWeight4Values = + apfGWKFilter4Values[eResample]; + CPLAssert(pfnGetWeight4Values); + + int i = iMin; // Used after for. + int iC = 0; // Used after for. + double dfAccumulatorWeightHorizontal = 0.0; + for (; i + 2 < iMax; i += 4, iC += 4) + { + padfWeightsHorizontal[iC] = (i - dfDeltaX) * dfXScale; + padfWeightsHorizontal[iC + 1] = padfWeightsHorizontal[iC] + dfXScale; + padfWeightsHorizontal[iC + 2] = + padfWeightsHorizontal[iC + 1] + dfXScale; + padfWeightsHorizontal[iC + 3] = + padfWeightsHorizontal[iC + 2] + dfXScale; + dfAccumulatorWeightHorizontal += + pfnGetWeight4Values(padfWeightsHorizontal + iC); + } + for (; i <= iMax; ++i, ++iC) + { + const double dfWeight = pfnGetWeight((i - dfDeltaX) * dfXScale); + padfWeightsHorizontal[iC] = dfWeight; + dfAccumulatorWeightHorizontal += dfWeight; + } + + int j = jMin; // Used after for. + int jC = 0; // Used after for. + double dfAccumulatorWeightVertical = 0.0; + for (; j + 2 < jMax; j += 4, jC += 4) + { + padfWeightsVertical[jC] = (j - dfDeltaY) * dfYScale; + padfWeightsVertical[jC + 1] = padfWeightsVertical[jC] + dfYScale; + padfWeightsVertical[jC + 2] = padfWeightsVertical[jC + 1] + dfYScale; + padfWeightsVertical[jC + 3] = padfWeightsVertical[jC + 2] + dfYScale; + dfAccumulatorWeightVertical += + pfnGetWeight4Values(padfWeightsVertical + jC); + } + for (; j <= jMax; ++j, ++jC) + { + const double dfWeight = pfnGetWeight((j - dfDeltaY) * dfYScale); + padfWeightsVertical[jC] = dfWeight; + dfAccumulatorWeightVertical += dfWeight; + } + + dfInvWeights = + 1. / (dfAccumulatorWeightHorizontal * dfAccumulatorWeightVertical); +} + /************************************************************************/ /* GWKResampleNoMasksT() */ /************************************************************************/ template -static bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, - double dfSrcX, double dfSrcY, T *pValue, - double *padfWeight) +static bool +GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, + double dfSrcY, T *pValue, double *padfWeightsHorizontal, + double *padfWeightsVertical, double &dfInvWeights) { // Commonly used; save locally. @@ -4148,52 +4455,33 @@ static bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, const double dfDeltaX = dfSrcX - 0.5 - iSrcX; const double dfDeltaY = dfSrcY - 0.5 - iSrcY; - const FilterFuncType pfnGetWeight = apfGWKFilter[poWK->eResample]; - CPLAssert(pfnGetWeight); - const FilterFunc4ValuesType pfnGetWeight4Values = - apfGWKFilter4Values[poWK->eResample]; - CPLAssert(pfnGetWeight4Values); - const double dfXScale = std::min(poWK->dfXScale, 1.0); const double dfYScale = std::min(poWK->dfYScale, 1.0); - // Loop over all rows in the kernel. - double dfAccumulatorWeightHorizontal = 0.0; - double dfAccumulatorWeightVertical = 0.0; - int iMin = 1 - nXRadius; if (iSrcX + iMin < 0) iMin = -iSrcX; int iMax = nXRadius; if (iSrcX + iMax >= nSrcXSize - 1) iMax = nSrcXSize - 1 - iSrcX; - int i = iMin; // Used after for. - int iC = 0; // Used after for. - for (; i + 2 < iMax; i += 4, iC += 4) - { - padfWeight[iC] = (i - dfDeltaX) * dfXScale; - padfWeight[iC + 1] = padfWeight[iC] + dfXScale; - padfWeight[iC + 2] = padfWeight[iC + 1] + dfXScale; - padfWeight[iC + 3] = padfWeight[iC + 2] + dfXScale; - dfAccumulatorWeightHorizontal += pfnGetWeight4Values(padfWeight + iC); - } - for (; i <= iMax; ++i, ++iC) - { - const double dfWeight = pfnGetWeight((i - dfDeltaX) * dfXScale); - padfWeight[iC] = dfWeight; - dfAccumulatorWeightHorizontal += dfWeight; - } - int j = 1 - nYRadius; - if (iSrcY + j < 0) - j = -iSrcY; + int jMin = 1 - nYRadius; + if (iSrcY + jMin < 0) + jMin = -iSrcY; int jMax = nYRadius; if (iSrcY + jMax >= nSrcYSize - 1) jMax = nSrcYSize - 1 - iSrcY; - double dfAccumulator = 0.0; + if (iBand == 0) + { + GWKComputeWeights(poWK->eResample, iMin, iMax, dfDeltaX, dfXScale, jMin, + jMax, dfDeltaY, dfYScale, padfWeightsHorizontal, + padfWeightsVertical, dfInvWeights); + } - for (; j <= jMax; ++j) + // Loop over all rows in the kernel. + double dfAccumulator = 0.0; + for (int jC = 0, j = jMin; j <= jMax; ++j, ++jC) { const GPtrDiff_t iSampJ = iSrcOffset + static_cast(j) * nSrcXSize; @@ -4201,42 +4489,41 @@ static bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, // Loop over all pixels in the row. double dfAccumulatorLocal = 0.0; double dfAccumulatorLocal2 = 0.0; - iC = 0; - i = iMin; + int iC = 0; + int i = iMin; // Process by chunk of 4 cols. for (; i + 2 < iMax; i += 4, iC += 4) { // Retrieve the pixel & accumulate. - dfAccumulatorLocal += pSrcBand[i + iSampJ] * padfWeight[iC]; - dfAccumulatorLocal += pSrcBand[i + 1 + iSampJ] * padfWeight[iC + 1]; + dfAccumulatorLocal += + pSrcBand[i + iSampJ] * padfWeightsHorizontal[iC]; + dfAccumulatorLocal += + pSrcBand[i + 1 + iSampJ] * padfWeightsHorizontal[iC + 1]; dfAccumulatorLocal2 += - pSrcBand[i + 2 + iSampJ] * padfWeight[iC + 2]; + pSrcBand[i + 2 + iSampJ] * padfWeightsHorizontal[iC + 2]; dfAccumulatorLocal2 += - pSrcBand[i + 3 + iSampJ] * padfWeight[iC + 3]; + pSrcBand[i + 3 + iSampJ] * padfWeightsHorizontal[iC + 3]; } dfAccumulatorLocal += dfAccumulatorLocal2; if (i < iMax) { - dfAccumulatorLocal += pSrcBand[i + iSampJ] * padfWeight[iC]; - dfAccumulatorLocal += pSrcBand[i + 1 + iSampJ] * padfWeight[iC + 1]; + dfAccumulatorLocal += + pSrcBand[i + iSampJ] * padfWeightsHorizontal[iC]; + dfAccumulatorLocal += + pSrcBand[i + 1 + iSampJ] * padfWeightsHorizontal[iC + 1]; i += 2; iC += 2; } if (i == iMax) { - dfAccumulatorLocal += pSrcBand[i + iSampJ] * padfWeight[iC]; + dfAccumulatorLocal += + pSrcBand[i + iSampJ] * padfWeightsHorizontal[iC]; } - // Calculate the Y weight. - const double dfWeight = pfnGetWeight((j - dfDeltaY) * dfYScale); - dfAccumulator += dfWeight * dfAccumulatorLocal; - dfAccumulatorWeightVertical += dfWeight; + dfAccumulator += padfWeightsVertical[jC] * dfAccumulatorLocal; } - const double dfAccumulatorWeight = - dfAccumulatorWeightHorizontal * dfAccumulatorWeightVertical; - - *pValue = GWKClampValueT(dfAccumulator / dfAccumulatorWeight); + *pValue = GWKClampValueT(dfAccumulator * dfInvWeights); return true; } @@ -4252,7 +4539,9 @@ static bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, template static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, T *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { // Commonly used; save locally. const int nSrcXSize = poWK->nSrcXSize; @@ -4274,60 +4563,42 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, const T *pSrcBand = reinterpret_cast(poWK->papabySrcImage[iBand]); - const FilterFuncType pfnGetWeight = apfGWKFilter[poWK->eResample]; - CPLAssert(pfnGetWeight); - const FilterFunc4ValuesType pfnGetWeight4Values = - apfGWKFilter4Values[poWK->eResample]; - CPLAssert(pfnGetWeight4Values); - const double dfDeltaX = dfSrcX - 0.5 - iSrcX; const double dfDeltaY = dfSrcY - 0.5 - iSrcY; const double dfXScale = std::min(poWK->dfXScale, 1.0); const double dfYScale = std::min(poWK->dfYScale, 1.0); - // Loop over all rows in the kernel. - double dfAccumulatorWeightHorizontal = 0.0; - double dfAccumulatorWeightVertical = 0.0; - double dfAccumulator = 0.0; - int iMin = 1 - nXRadius; if (iSrcX + iMin < 0) iMin = -iSrcX; int iMax = nXRadius; if (iSrcX + iMax >= nSrcXSize - 1) iMax = nSrcXSize - 1 - iSrcX; - int i, iC; - for (iC = 0, i = iMin; i + 2 < iMax; i += 4, iC += 4) - { - padfWeight[iC] = (i - dfDeltaX) * dfXScale; - padfWeight[iC + 1] = padfWeight[iC] + dfXScale; - padfWeight[iC + 2] = padfWeight[iC + 1] + dfXScale; - padfWeight[iC + 3] = padfWeight[iC + 2] + dfXScale; - dfAccumulatorWeightHorizontal += pfnGetWeight4Values(padfWeight + iC); - } - for (; i <= iMax; ++i, ++iC) - { - double dfWeight = pfnGetWeight((i - dfDeltaX) * dfXScale); - padfWeight[iC] = dfWeight; - dfAccumulatorWeightHorizontal += dfWeight; - } - int j = 1 - nYRadius; - if (iSrcY + j < 0) - j = -iSrcY; + int jMin = 1 - nYRadius; + if (iSrcY + jMin < 0) + jMin = -iSrcY; int jMax = nYRadius; if (iSrcY + jMax >= nSrcYSize - 1) jMax = nSrcYSize - 1 - iSrcY; - // Process by chunk of 4 rows. - for (; j + 2 < jMax; j += 4) + if (iBand == 0) { - const GPtrDiff_t iSampJ = - iSrcOffset + static_cast(j) * nSrcXSize; + GWKComputeWeights(poWK->eResample, iMin, iMax, dfDeltaX, dfXScale, jMin, + jMax, dfDeltaY, dfYScale, padfWeightsHorizontal, + padfWeightsVertical, dfInvWeights); + } + GPtrDiff_t iSampJ = iSrcOffset + static_cast(jMin) * nSrcXSize; + // Process by chunk of 4 rows. + int jC = 0; + int j = jMin; + double dfAccumulator = 0.0; + for (; j + 2 < jMax; j += 4, iSampJ += 4 * nSrcXSize, jC += 4) + { // Loop over all pixels in the row. - iC = 0; - i = iMin; + int iC = 0; + int i = iMin; // Process by chunk of 4 cols. XMMReg4Double v_acc_1 = XMMReg4Double::Zero(); XMMReg4Double v_acc_2 = XMMReg4Double::Zero(); @@ -4346,7 +4617,7 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, XMMReg4Double::Load4Val(pSrcBand + i + iSampJ + 3 * nSrcXSize); XMMReg4Double v_padfWeight = - XMMReg4Double::Load4Val(padfWeight + iC); + XMMReg4Double::Load4Val(padfWeightsHorizontal + iC); v_acc_1 += v_pixels_1 * v_padfWeight; v_acc_2 += v_pixels_2 * v_padfWeight; @@ -4366,7 +4637,7 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, XMMReg2Double::Load2Val(pSrcBand + i + iSampJ + 3 * nSrcXSize); XMMReg2Double v_padfWeight = - XMMReg2Double::Load2Val(padfWeight + iC); + XMMReg2Double::Load2Val(padfWeightsHorizontal + iC); v_acc_1.AddToLow(v_pixels_1 * v_padfWeight); v_acc_2.AddToLow(v_pixels_2 * v_padfWeight); @@ -4384,40 +4655,29 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, if (i == iMax) { - dfAccumulatorLocal_1 += - static_cast(pSrcBand[i + iSampJ]) * padfWeight[iC]; + dfAccumulatorLocal_1 += static_cast(pSrcBand[i + iSampJ]) * + padfWeightsHorizontal[iC]; dfAccumulatorLocal_2 += static_cast(pSrcBand[i + iSampJ + nSrcXSize]) * - padfWeight[iC]; + padfWeightsHorizontal[iC]; dfAccumulatorLocal_3 += static_cast(pSrcBand[i + iSampJ + 2 * nSrcXSize]) * - padfWeight[iC]; + padfWeightsHorizontal[iC]; dfAccumulatorLocal_4 += static_cast(pSrcBand[i + iSampJ + 3 * nSrcXSize]) * - padfWeight[iC]; + padfWeightsHorizontal[iC]; } - // Calculate the Y weight. - const double dfWeight0 = (j - dfDeltaY) * dfYScale; - const double dfWeight1 = dfWeight0 + dfYScale; - const double dfWeight2 = dfWeight1 + dfYScale; - const double dfWeight3 = dfWeight2 + dfYScale; - double adfWeight[4] = {dfWeight0, dfWeight1, dfWeight2, dfWeight3}; - - dfAccumulatorWeightVertical += pfnGetWeight4Values(adfWeight); - dfAccumulator += adfWeight[0] * dfAccumulatorLocal_1; - dfAccumulator += adfWeight[1] * dfAccumulatorLocal_2; - dfAccumulator += adfWeight[2] * dfAccumulatorLocal_3; - dfAccumulator += adfWeight[3] * dfAccumulatorLocal_4; + dfAccumulator += padfWeightsVertical[jC] * dfAccumulatorLocal_1; + dfAccumulator += padfWeightsVertical[jC + 1] * dfAccumulatorLocal_2; + dfAccumulator += padfWeightsVertical[jC + 2] * dfAccumulatorLocal_3; + dfAccumulator += padfWeightsVertical[jC + 3] * dfAccumulatorLocal_4; } - for (; j <= jMax; ++j) + for (; j <= jMax; ++j, iSampJ += nSrcXSize, ++jC) { - const GPtrDiff_t iSampJ = - iSrcOffset + static_cast(j) * nSrcXSize; - // Loop over all pixels in the row. - iC = 0; - i = iMin; + int iC = 0; + int i = iMin; // Process by chunk of 4 cols. XMMReg4Double v_acc = XMMReg4Double::Zero(); for (; i + 2 < iMax; i += 4, iC += 4) @@ -4426,7 +4686,7 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, XMMReg4Double v_pixels = XMMReg4Double::Load4Val(pSrcBand + i + iSampJ); XMMReg4Double v_padfWeight = - XMMReg4Double::Load4Val(padfWeight + iC); + XMMReg4Double::Load4Val(padfWeightsHorizontal + iC); v_acc += v_pixels * v_padfWeight; } @@ -4435,27 +4695,23 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, if (i < iMax) { - dfAccumulatorLocal += pSrcBand[i + iSampJ] * padfWeight[iC]; - dfAccumulatorLocal += pSrcBand[i + 1 + iSampJ] * padfWeight[iC + 1]; + dfAccumulatorLocal += + pSrcBand[i + iSampJ] * padfWeightsHorizontal[iC]; + dfAccumulatorLocal += + pSrcBand[i + 1 + iSampJ] * padfWeightsHorizontal[iC + 1]; i += 2; iC += 2; } if (i == iMax) { - dfAccumulatorLocal += - static_cast(pSrcBand[i + iSampJ]) * padfWeight[iC]; + dfAccumulatorLocal += static_cast(pSrcBand[i + iSampJ]) * + padfWeightsHorizontal[iC]; } - // Calculate the Y weight. - double dfWeight = pfnGetWeight((j - dfDeltaY) * dfYScale); - dfAccumulator += dfWeight * dfAccumulatorLocal; - dfAccumulatorWeightVertical += dfWeight; + dfAccumulator += padfWeightsVertical[jC] * dfAccumulatorLocal; } - const double dfAccumulatorWeight = - dfAccumulatorWeightHorizontal * dfAccumulatorWeightVertical; - - *pValue = GWKClampValueT(dfAccumulator / dfAccumulatorWeight); + *pValue = GWKClampValueT(dfAccumulator * dfInvWeights); return true; } @@ -4467,10 +4723,13 @@ static bool GWKResampleNoMasks_SSE2_T(const GDALWarpKernel *poWK, int iBand, template <> bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, GByte *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { return GWKResampleNoMasks_SSE2_T(poWK, iBand, dfSrcX, dfSrcY, pValue, - padfWeight); + padfWeightsHorizontal, padfWeightsVertical, + dfInvWeights); } /************************************************************************/ @@ -4480,10 +4739,13 @@ bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, template <> bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, GInt16 *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { return GWKResampleNoMasks_SSE2_T(poWK, iBand, dfSrcX, dfSrcY, pValue, - padfWeight); + padfWeightsHorizontal, padfWeightsVertical, + dfInvWeights); } /************************************************************************/ @@ -4493,10 +4755,13 @@ bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, template <> bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, GUInt16 *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { return GWKResampleNoMasks_SSE2_T(poWK, iBand, dfSrcX, dfSrcY, pValue, - padfWeight); + padfWeightsHorizontal, padfWeightsVertical, + dfInvWeights); } /************************************************************************/ @@ -4506,10 +4771,13 @@ bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, template <> bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, float *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { return GWKResampleNoMasks_SSE2_T(poWK, iBand, dfSrcX, dfSrcY, pValue, - padfWeight); + padfWeightsHorizontal, padfWeightsVertical, + dfInvWeights); } #ifdef INSTANTIATE_FLOAT64_SSE2_IMPL @@ -4521,10 +4789,13 @@ bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, template <> bool GWKResampleNoMasksT(const GDALWarpKernel *poWK, int iBand, double dfSrcX, double dfSrcY, double *pValue, - double *padfWeight) + double *padfWeightsHorizontal, + double *padfWeightsVertical, + double &dfInvWeights) { return GWKResampleNoMasks_SSE2_T(poWK, iBand, dfSrcX, dfSrcY, pValue, - padfWeight); + padfWeightsHorizontal, padfWeightsVertical, + dfInvWeights); } #endif /* INSTANTIATE_FLOAT64_SSE2_IMPL */ @@ -5843,6 +6114,141 @@ static CPLErr GWKRealCase(GDALWarpKernel *poWK) return GWKRun(poWK, "GWKRealCase", GWKRealCaseThread); } +/************************************************************************/ +/* GWKCubicResampleNoMasks4MultiBandT() */ +/************************************************************************/ + +/* We restrict to 64bit processors because they are guaranteed to have SSE2 */ +/* and enough SSE registries */ +#if defined(__x86_64) || defined(_M_X64) + +static inline float Convolute4x4(const __m128 row0, const __m128 row1, + const __m128 row2, const __m128 row3, + const __m128 weightsXY0, + const __m128 weightsXY1, + const __m128 weightsXY2, + const __m128 weightsXY3) +{ + return XMMHorizontalAdd(_mm_add_ps( + _mm_add_ps(_mm_mul_ps(row0, weightsXY0), _mm_mul_ps(row1, weightsXY1)), + _mm_add_ps(_mm_mul_ps(row2, weightsXY2), + _mm_mul_ps(row3, weightsXY3)))); +} + +template +static void GWKCubicResampleNoMasks4MultiBandT(const GDALWarpKernel *poWK, + double dfSrcX, double dfSrcY, + const GPtrDiff_t iDstOffset) +{ + const double dfSrcXShifted = dfSrcX - 0.5; + const int iSrcX = static_cast(dfSrcXShifted); + const double dfSrcYShifted = dfSrcY - 0.5; + const int iSrcY = static_cast(dfSrcYShifted); + const GPtrDiff_t iSrcOffset = + iSrcX + static_cast(iSrcY) * poWK->nSrcXSize; + + // Get the bilinear interpolation at the image borders. + if (iSrcX - 1 < 0 || iSrcX + 2 >= poWK->nSrcXSize || iSrcY - 1 < 0 || + iSrcY + 2 >= poWK->nSrcYSize) + { + for (int iBand = 0; iBand < poWK->nBands; iBand++) + { + T value; + GWKBilinearResampleNoMasks4SampleT(poWK, iBand, dfSrcX, dfSrcY, + &value); + reinterpret_cast(poWK->papabyDstImage[iBand])[iDstOffset] = + value; + } + } + else + { + const float fDeltaX = static_cast(dfSrcXShifted) - iSrcX; + const float fDeltaY = static_cast(dfSrcYShifted) - iSrcY; + + float afCoeffsX[4]; + float afCoeffsY[4]; + GWKCubicComputeWeights(fDeltaX, afCoeffsX); + GWKCubicComputeWeights(fDeltaY, afCoeffsY); + const auto weightsX = _mm_loadu_ps(afCoeffsX); + const auto weightsXY0 = + _mm_mul_ps(_mm_load1_ps(&afCoeffsY[0]), weightsX); + const auto weightsXY1 = + _mm_mul_ps(_mm_load1_ps(&afCoeffsY[1]), weightsX); + const auto weightsXY2 = + _mm_mul_ps(_mm_load1_ps(&afCoeffsY[2]), weightsX); + const auto weightsXY3 = + _mm_mul_ps(_mm_load1_ps(&afCoeffsY[3]), weightsX); + + const GPtrDiff_t iOffset = iSrcOffset - poWK->nSrcXSize - 1; + + int iBand = 0; + // Process 2 bands at a time + for (; iBand + 1 < poWK->nBands; iBand += 2) + { + const T *CPL_RESTRICT pBand0 = + reinterpret_cast(poWK->papabySrcImage[iBand]); + const auto row0_0 = XMMLoad4Values(pBand0 + iOffset); + const auto row1_0 = + XMMLoad4Values(pBand0 + iOffset + poWK->nSrcXSize); + const auto row2_0 = + XMMLoad4Values(pBand0 + iOffset + 2 * poWK->nSrcXSize); + const auto row3_0 = + XMMLoad4Values(pBand0 + iOffset + 3 * poWK->nSrcXSize); + + const T *CPL_RESTRICT pBand1 = + reinterpret_cast(poWK->papabySrcImage[iBand + 1]); + const auto row0_1 = XMMLoad4Values(pBand1 + iOffset); + const auto row1_1 = + XMMLoad4Values(pBand1 + iOffset + poWK->nSrcXSize); + const auto row2_1 = + XMMLoad4Values(pBand1 + iOffset + 2 * poWK->nSrcXSize); + const auto row3_1 = + XMMLoad4Values(pBand1 + iOffset + 3 * poWK->nSrcXSize); + + const float fValue_0 = + Convolute4x4(row0_0, row1_0, row2_0, row3_0, weightsXY0, + weightsXY1, weightsXY2, weightsXY3); + + const float fValue_1 = + Convolute4x4(row0_1, row1_1, row2_1, row3_1, weightsXY0, + weightsXY1, weightsXY2, weightsXY3); + + T *CPL_RESTRICT pDstBand0 = + reinterpret_cast(poWK->papabyDstImage[iBand]); + pDstBand0[iDstOffset] = GWKClampValueT(fValue_0); + + T *CPL_RESTRICT pDstBand1 = + reinterpret_cast(poWK->papabyDstImage[iBand + 1]); + pDstBand1[iDstOffset] = GWKClampValueT(fValue_1); + } + if (iBand < poWK->nBands) + { + const T *CPL_RESTRICT pBand0 = + reinterpret_cast(poWK->papabySrcImage[iBand]); + const auto row0 = XMMLoad4Values(pBand0 + iOffset); + const auto row1 = + XMMLoad4Values(pBand0 + iOffset + poWK->nSrcXSize); + const auto row2 = + XMMLoad4Values(pBand0 + iOffset + 2 * poWK->nSrcXSize); + const auto row3 = + XMMLoad4Values(pBand0 + iOffset + 3 * poWK->nSrcXSize); + + const float fValue = + Convolute4x4(row0, row1, row2, row3, weightsXY0, weightsXY1, + weightsXY2, weightsXY3); + + T *CPL_RESTRICT pDstBand = + reinterpret_cast(poWK->papabyDstImage[iBand]); + pDstBand[iDstOffset] = GWKClampValueT(fValue); + } + } + + if (poWK->pafDstDensity) + poWK->pafDstDensity[iDstOffset] = 1.0f; +} + +#endif // defined(__x86_64) || defined(_M_X64) + /************************************************************************/ /* GWKResampleNoMasksOrDstDensityOnlyThreadInternal() */ /************************************************************************/ @@ -5881,8 +6287,10 @@ static void GWKResampleNoMasksOrDstDensityOnlyThreadInternal(void *pData) int *pabSuccess = static_cast(CPLMalloc(sizeof(int) * nDstXSize)); const int nXRadius = poWK->nXRadius; - double *padfWeight = + double *padfWeightsX = static_cast(CPLCalloc(1 + nXRadius * 2, sizeof(double))); + double *padfWeightsY = static_cast( + CPLCalloc(1 + poWK->nYRadius * 2, sizeof(double))); const double dfSrcCoordPrecision = CPLAtof(CSLFetchNameValueDef( poWK->papszWarpOptions, "SRC_COORD_PRECISION", "0")); const double dfErrorThreshold = CPLAtof( @@ -5945,6 +6353,23 @@ static void GWKResampleNoMasksOrDstDensityOnlyThreadInternal(void *pData) const GPtrDiff_t iDstOffset = iDstX + static_cast(iDstY) * nDstXSize; +#if defined(__x86_64) || defined(_M_X64) + if constexpr (bUse4SamplesFormula && eResample == GRA_Cubic && + (std::is_same::value || + std::is_same::value)) + { + if (poWK->nBands > 1 && !poWK->bApplyVerticalShift) + { + GWKCubicResampleNoMasks4MultiBandT( + poWK, padfX[iDstX] - poWK->nSrcXOff, + padfY[iDstX] - poWK->nSrcYOff, iDstOffset); + + continue; + } + } +#endif // defined(__x86_64) || defined(_M_X64) + + [[maybe_unused]] double dfInvWeights = 0; for (int iBand = 0; iBand < poWK->nBands; iBand++) { T value = 0; @@ -5968,7 +6393,8 @@ static void GWKResampleNoMasksOrDstDensityOnlyThreadInternal(void *pData) { GWKResampleNoMasksT( poWK, iBand, padfX[iDstX] - poWK->nSrcXOff, - padfY[iDstX] - poWK->nSrcYOff, &value, padfWeight); + padfY[iDstX] - poWK->nSrcYOff, &value, padfWeightsX, + padfWeightsY, dfInvWeights); } if (poWK->bApplyVerticalShift) @@ -6006,7 +6432,8 @@ static void GWKResampleNoMasksOrDstDensityOnlyThreadInternal(void *pData) CPLFree(padfY); CPLFree(padfZ); CPLFree(pabSuccess); - CPLFree(padfWeight); + CPLFree(padfWeightsX); + CPLFree(padfWeightsY); } template @@ -6685,9 +7112,26 @@ static void GWKAverageOrModeThread(void *pData) (nSrcXSize - padfX2[iDstX]) * poWK->dfXScale < nThresholdWrapOverX) { - bWrapOverX = true; - std::swap(padfX[iDstX], padfX2[iDstX]); - padfX2[iDstX] += nSrcXSize; + // Check there is a discontinuity by checking at mid-pixel. + // NOTE: all this remains fragile. To confidently + // detect antimeridian warping we should probably try to access + // georeferenced coordinates, and not rely only on tests on + // image space coordinates. But accessing georeferenced + // coordinates from here is not trivial, and we would for example + // have to handle both geographic, Mercator, etc. + // Let's hope this heuristics is good enough for now. + double x = iDstX + 0.5 + poWK->nDstXOff; + double y = iDstY + poWK->nDstYOff; + double z = 0; + int bSuccess = FALSE; + poWK->pfnTransformer(psJob->pTransformerArg, TRUE, 1, &x, &y, + &z, &bSuccess); + if (bSuccess && x < padfX[iDstX]) + { + bWrapOverX = true; + std::swap(padfX[iDstX], padfX2[iDstX]); + padfX2[iDstX] += nSrcXSize; + } } const double dfXMin = padfX[iDstX] - poWK->nSrcXOff; diff --git a/alg/gdalwarpkernel_opencl.cpp b/alg/gdalwarpkernel_opencl.cpp index 8d46fa2cbc6e..355ea93df6c8 100644 --- a/alg/gdalwarpkernel_opencl.cpp +++ b/alg/gdalwarpkernel_opencl.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2010, Seth Price * Copyright (c) 2010-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/alg/gdalwarpkernel_opencl.h b/alg/gdalwarpkernel_opencl.h index bd61ccf4141c..39659f01e1b6 100644 --- a/alg/gdalwarpkernel_opencl.h +++ b/alg/gdalwarpkernel_opencl.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2010, Seth Price * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #if defined(HAVE_OPENCL) diff --git a/alg/gdalwarpoperation.cpp b/alg/gdalwarpoperation.cpp index 1448de37f95b..35a71726faf9 100644 --- a/alg/gdalwarpoperation.cpp +++ b/alg/gdalwarpoperation.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2003, Frank Warmerdam * Copyright (c) 2007-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -694,10 +678,40 @@ void *GDALWarpOperation::CreateDestinationBuffer(int nDstXSize, int nDstYSize, void *pDstBuffer = VSI_MALLOC3_VERBOSE( cpl::fits_on(nWordSize * psOptions->nBandCount), nDstXSize, nDstYSize); - if (pDstBuffer == nullptr) + if (pDstBuffer) { - return nullptr; + InitializeDestinationBuffer(pDstBuffer, nDstXSize, nDstYSize, + pbInitialized); } + return pDstBuffer; +} + +/** + * This method initializes a destination buffer for use with WarpRegionToBuffer. + * + * It is initialized based on the INIT_DEST settings. + * + * This method is called by CreateDestinationBuffer(). + * It is meant at being used by callers that have already allocated the + * destination buffer without using CreateDestinationBuffer(). + * + * @param pDstBuffer Buffer of size + * GDALGetDataTypeSizeBytes(psOptions->eWorkingDataType) * + * nDstXSize * nDstYSize * psOptions->nBandCount bytes. + * @param nDstXSize Width of output window on destination buffer to be produced. + * @param nDstYSize Height of output window on destination buffer to be + * produced. + * @param pbInitialized Filled with boolean indicating if the buffer was + * initialized. + * @since 3.10 + */ +void GDALWarpOperation::InitializeDestinationBuffer(void *pDstBuffer, + int nDstXSize, + int nDstYSize, + int *pbInitialized) +{ + const int nWordSize = GDALGetDataTypeSizeBytes(psOptions->eWorkingDataType); + const GPtrDiff_t nBandSize = static_cast(nWordSize) * nDstXSize * nDstYSize; @@ -713,8 +727,7 @@ void *GDALWarpOperation::CreateDestinationBuffer(int nDstXSize, int nDstYSize, { *pbInitialized = FALSE; } - - return pDstBuffer; + return; } if (pbInitialized != nullptr) @@ -776,8 +789,6 @@ void *GDALWarpOperation::CreateDestinationBuffer(int nDstXSize, int nDstYSize, } CSLDestroy(papszInitValues); - - return pDstBuffer; } /** @@ -832,22 +843,6 @@ void GDALDestroyWarpOperation(GDALWarpOperationH hOperation) /* CollectChunkList() */ /************************************************************************/ -static int OrderWarpChunk(const void *_a, const void *_b) -{ - const GDALWarpChunk *a = static_cast(_a); - const GDALWarpChunk *b = static_cast(_b); - if (a->dy < b->dy) - return -1; - else if (a->dy > b->dy) - return 1; - else if (a->dx < b->dx) - return -1; - else if (a->dx > b->dx) - return 1; - else - return 0; -} - void GDALWarpOperation::CollectChunkList(int nDstXOff, int nDstYOff, int nDstXSize, int nDstYSize) @@ -859,10 +854,18 @@ void GDALWarpOperation::CollectChunkList(int nDstXOff, int nDstYOff, CollectChunkListInternal(nDstXOff, nDstYOff, nDstXSize, nDstYSize); // Sort chunks from top to bottom, and for equal y, from left to right. - // TODO(schwehr): Use std::sort. - if (pasChunkList) - qsort(pasChunkList, nChunkListCount, sizeof(GDALWarpChunk), - OrderWarpChunk); + if (nChunkListCount > 1) + { + std::sort(pasChunkList, pasChunkList + nChunkListCount, + [](const GDALWarpChunk &a, const GDALWarpChunk &b) + { + if (a.dy < b.dy) + return true; + if (a.dy > b.dy) + return false; + return a.dx < b.dx; + }); + } /* -------------------------------------------------------------------- */ /* Find the global source window. */ @@ -1264,7 +1267,7 @@ void GDALWarpOperation::WipeChunkList() /* GetWorkingMemoryForWindow() */ /************************************************************************/ -/** Retrurns the amount of working memory, in bytes, required to process +/** Returns the amount of working memory, in bytes, required to process * a warped window of source dimensions nSrcXSize x nSrcYSize and target * dimensions nDstXSize x nDstYSize. */ diff --git a/alg/internal_qhull_headers.h b/alg/internal_qhull_headers.h index e33e539eb882..18d66e8f162c 100644 --- a/alg/internal_qhull_headers.h +++ b/alg/internal_qhull_headers.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #ifndef INTERNAL_QHULL_HEADERS_H diff --git a/alg/llrasterize.cpp b/alg/llrasterize.cpp index 5034ff3816d6..8b0d1e93baf7 100644 --- a/alg/llrasterize.cpp +++ b/alg/llrasterize.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2000, Frank Warmerdam * Copyright (c) 2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/los.cpp b/alg/los.cpp index fda7019cf469..0cf271120043 100644 --- a/alg/los.cpp +++ b/alg/los.cpp @@ -6,23 +6,7 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/alg/marching_squares/contour_generator.h b/alg/marching_squares/contour_generator.h index f0c5af1c1f9b..b9f349284d66 100644 --- a/alg/marching_squares/contour_generator.h +++ b/alg/marching_squares/contour_generator.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARES_CONTOUR_GENERATOR_H diff --git a/alg/marching_squares/level_generator.h b/alg/marching_squares/level_generator.h index 32d35622b160..39310e02d5ba 100644 --- a/alg/marching_squares/level_generator.h +++ b/alg/marching_squares/level_generator.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARE_LEVEL_GENERATOR_H #define MARCHING_SQUARE_LEVEL_GENERATOR_H diff --git a/alg/marching_squares/point.h b/alg/marching_squares/point.h index 66176d9d7f8e..aaef2d2dcc62 100644 --- a/alg/marching_squares/point.h +++ b/alg/marching_squares/point.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARE_POINT_H diff --git a/alg/marching_squares/polygon_ring_appender.h b/alg/marching_squares/polygon_ring_appender.h index 360a76370b6d..186140638841 100644 --- a/alg/marching_squares/polygon_ring_appender.h +++ b/alg/marching_squares/polygon_ring_appender.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARE_POLYGON_RING_APPENDER_H #define MARCHING_SQUARE_POLYGON_RING_APPENDER_H diff --git a/alg/marching_squares/segment_merger.h b/alg/marching_squares/segment_merger.h index a7d095f1c023..f3557f3f4e45 100644 --- a/alg/marching_squares/segment_merger.h +++ b/alg/marching_squares/segment_merger.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARES_SEGMENT_MERGER_H #define MARCHING_SQUARES_SEGMENT_MERGER_H @@ -81,12 +65,12 @@ template struct SegmentMerger } } - void addBorderSegment(int levelIdx, const Point &start, const Point &end) + void addSegment(int levelIdx, const Point &start, const Point &end) { addSegment_(levelIdx, start, end); } - void addSegment(int levelIdx, const Point &start, const Point &end) + void addBorderSegment(int levelIdx, const Point &start, const Point &end) { addSegment_(levelIdx, start, end); } diff --git a/alg/marching_squares/square.h b/alg/marching_squares/square.h index 68dab5b5ddff..3b6d0a9d2bc1 100644 --- a/alg/marching_squares/square.h +++ b/alg/marching_squares/square.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARE_SQUARE_H #define MARCHING_SQUARE_SQUARE_H diff --git a/alg/marching_squares/utility.h b/alg/marching_squares/utility.h index eef8252a30cf..551b8d89b2b2 100644 --- a/alg/marching_squares/utility.h +++ b/alg/marching_squares/utility.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef MARCHING_SQUARE_UTILITY_H #define MARCHING_SQUARE_UTILITY_H diff --git a/alg/polygonize.cpp b/alg/polygonize.cpp index 4feb4edb1a79..7b7f5f014bdd 100644 --- a/alg/polygonize.cpp +++ b/alg/polygonize.cpp @@ -7,23 +7,7 @@ * Copyright (c) 2008, Frank Warmerdam * Copyright (c) 2009-2020, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/alg/polygonize_polygonizer.cpp b/alg/polygonize_polygonizer.cpp index 014962cd7314..80f2437301a2 100644 --- a/alg/polygonize_polygonizer.cpp +++ b/alg/polygonize_polygonizer.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2023, kikitte.lee * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /*! @cond Doxygen_Suppress */ diff --git a/alg/polygonize_polygonizer.h b/alg/polygonize_polygonizer.h index 6688ec894aee..349b7862d766 100644 --- a/alg/polygonize_polygonizer.h +++ b/alg/polygonize_polygonizer.h @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2023, kikitte.lee * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef POLYGONIZE_POLYGONIZER_H_INCLUDED diff --git a/alg/rasterfill.cpp b/alg/rasterfill.cpp index 45ce9aec657b..3be8db9d3f8d 100644 --- a/alg/rasterfill.cpp +++ b/alg/rasterfill.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2009-2013, Even Rouault * Copyright (c) 2015, Sean Gillies * - * 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. + * SPDX-License-Identifier: MIT ***************************************************************************/ #include "cpl_port.h" diff --git a/alg/thinplatespline.cpp b/alg/thinplatespline.cpp index 5590653c7787..651ef229f975 100644 --- a/alg/thinplatespline.cpp +++ b/alg/thinplatespline.cpp @@ -11,23 +11,7 @@ * Copyright (c) 2004, VIZRT Inc. * Copyright (c) 2008-2014, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ /*! @cond Doxygen_Suppress */ diff --git a/alg/thinplatespline.h b/alg/thinplatespline.h index c3f75a985776..6e08c4716f35 100644 --- a/alg/thinplatespline.h +++ b/alg/thinplatespline.h @@ -11,23 +11,7 @@ ****************************************************************************** * Copyright (c) 2004, VIZRT Inc. * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef THINPLATESPLINE_H_INCLUDED diff --git a/alg/viewshed/combiner.cpp b/alg/viewshed/combiner.cpp index 74f8b3f6c7bb..019b2c41fc4f 100644 --- a/alg/viewshed/combiner.cpp +++ b/alg/viewshed/combiner.cpp @@ -1,23 +1,7 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "combiner.h" diff --git a/alg/viewshed/combiner.h b/alg/viewshed/combiner.h index 4597a8fd8d9d..06f8772618d9 100644 --- a/alg/viewshed/combiner.h +++ b/alg/viewshed/combiner.h @@ -1,26 +1,11 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_COMBINER_H_INCLUDED +#define VIEWSHED_COMBINER_H_INCLUDED #include "cumulative.h" #include "viewshed_types.h" @@ -67,3 +52,5 @@ class Combiner } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/cumulative.cpp b/alg/viewshed/cumulative.cpp index 79d48c68c4d0..0111492a5b45 100644 --- a/alg/viewshed/cumulative.cpp +++ b/alg/viewshed/cumulative.cpp @@ -1,23 +1,7 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include @@ -44,6 +28,10 @@ Cumulative::Cumulative(const Options &opts) : m_opts(opts) { } +/// Destructor +/// +Cumulative::~Cumulative() = default; + /// Compute the cumulative viewshed of a raster band. /// /// @param srcFilename Source filename. diff --git a/alg/viewshed/cumulative.h b/alg/viewshed/cumulative.h index 1d93a0896368..1b80e9205617 100644 --- a/alg/viewshed/cumulative.h +++ b/alg/viewshed/cumulative.h @@ -1,26 +1,11 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_CUMULATIVE_H_INCLUDED +#define VIEWSHED_CUMULATIVE_H_INCLUDED #include #include @@ -41,6 +26,11 @@ class Cumulative { public: CPL_DLL explicit Cumulative(const Options &opts); + // We define an explicit destructor, whose implementation is in libgdal, + // otherwise with gcc 9.4 of Ubuntu 20.04 in debug mode, this would need to + // redefinition of the NotifyQueue class in both libgdal and gdal_viewshed, + // leading to weird things related to mutex. + CPL_DLL ~Cumulative(); CPL_DLL bool run(const std::string &srcFilename, GDALProgressFunc pfnProgress = GDALDummyProgress, void *pProgressArg = nullptr); @@ -70,7 +60,12 @@ class Cumulative void rollupRasters(); void scaleOutput(); bool writeOutput(DatasetPtr pDstDS); + + Cumulative(const Cumulative &) = delete; + Cumulative &operator=(const Cumulative &) = delete; }; } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/notifyqueue.h b/alg/viewshed/notifyqueue.h index 6ddeed8ec79d..af4cb75c1d71 100644 --- a/alg/viewshed/notifyqueue.h +++ b/alg/viewshed/notifyqueue.h @@ -1,25 +1,13 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once + +#ifndef VIEWSHED_NOTIFYQUEUE_H_INCLUDED +#define VIEWSHED_NOTIFYQUEUE_H_INCLUDED + +#include "cpl_port.h" #include #include @@ -134,3 +122,5 @@ template class NotifyQueue } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/progress.cpp b/alg/viewshed/progress.cpp index 3f02b324d9f8..d2bb5b803116 100644 --- a/alg/viewshed/progress.cpp +++ b/alg/viewshed/progress.cpp @@ -1,23 +1,7 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/alg/viewshed/progress.h b/alg/viewshed/progress.h index d0afaa588a97..b93bbb1de93d 100644 --- a/alg/viewshed/progress.h +++ b/alg/viewshed/progress.h @@ -1,26 +1,11 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_PROGRESS_H_INCLUDED +#define VIEWSHED_PROGRESS_H_INCLUDED #include #include @@ -54,3 +39,5 @@ class Progress } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/util.cpp b/alg/viewshed/util.cpp index cf935ed3b3c9..1b98496f8de1 100644 --- a/alg/viewshed/util.cpp +++ b/alg/viewshed/util.cpp @@ -1,23 +1,7 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/alg/viewshed/util.h b/alg/viewshed/util.h index 281bd382608f..7c92d9f8e938 100644 --- a/alg/viewshed/util.h +++ b/alg/viewshed/util.h @@ -1,26 +1,11 @@ /****************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_UTIL_H_INCLUDED +#define VIEWSHED_UTIL_H_INCLUDED #include "viewshed_types.h" @@ -36,3 +21,5 @@ DatasetPtr createOutputDataset(GDALRasterBand &srcBand, const Options &opts, } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/viewshed.cpp b/alg/viewshed/viewshed.cpp index fb0008ed7460..d9f0fc046234 100644 --- a/alg/viewshed/viewshed.cpp +++ b/alg/viewshed/viewshed.cpp @@ -8,23 +8,7 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include @@ -234,6 +218,12 @@ bool getTransforms(GDALRasterBand &band, double *pFwdTransform, } // unnamed namespace +Viewshed::Viewshed(const Options &opts) : oOpts{opts} +{ +} + +Viewshed::~Viewshed() = default; + /// Calculate the extent of the output raster in terms of the input raster and /// save the input raster extent. /// diff --git a/alg/viewshed/viewshed.h b/alg/viewshed/viewshed.h index 9109772d214d..648e939323f1 100644 --- a/alg/viewshed/viewshed.h +++ b/alg/viewshed/viewshed.h @@ -8,26 +8,11 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_H_INCLUDED +#define VIEWSHED_H_INCLUDED #include #include @@ -59,13 +44,10 @@ class Viewshed * * @param opts Options to use when calculating viewshed. */ - CPL_DLL explicit Viewshed(const Options &opts) - : oOpts{opts}, oOutExtent{}, oCurExtent{}, poDstDS{}, pSrcBand{} - { - } + CPL_DLL explicit Viewshed(const Options &opts); - Viewshed(const Viewshed &) = delete; - Viewshed &operator=(const Viewshed &) = delete; + /** Destructor */ + CPL_DLL ~Viewshed(); CPL_DLL bool run(GDALRasterBandH hBand, GDALProgressFunc pfnProgress = GDALDummyProgress, @@ -83,10 +65,10 @@ class Viewshed private: Options oOpts; - Window oOutExtent; - Window oCurExtent; - DatasetPtr poDstDS; - GDALRasterBand *pSrcBand; + Window oOutExtent{}; + Window oCurExtent{}; + DatasetPtr poDstDS{}; + GDALRasterBand *pSrcBand = nullptr; DatasetPtr execute(int nX, int nY, const std::string &outFilename); void setOutput(double &dfResult, double &dfCellVal, double dfZ); @@ -96,7 +78,12 @@ class Viewshed std::vector &thisLineVal); bool calcExtents(int nX, int nY, const std::array &adfInvTransform); + + Viewshed(const Viewshed &) = delete; + Viewshed &operator=(const Viewshed &) = delete; }; } // namespace viewshed } // namespace gdal + +#endif diff --git a/alg/viewshed/viewshed_executor.cpp b/alg/viewshed/viewshed_executor.cpp index 01a9d5e32658..3f54937553ca 100644 --- a/alg/viewshed/viewshed_executor.cpp +++ b/alg/viewshed/viewshed_executor.cpp @@ -8,23 +8,7 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include @@ -136,7 +120,7 @@ ViewshedExecutor::ViewshedExecutor(GDALRasterBand &srcBand, // calculate the height adjustment factor. double ViewshedExecutor::calcHeightAdjFactor() { - std::lock_guard g(iMutex); + std::lock_guard g(oMutex); const OGRSpatialReference *poDstSRS = m_dstBand.GetDataset()->GetSpatialRef(); diff --git a/alg/viewshed/viewshed_executor.h b/alg/viewshed/viewshed_executor.h index 291581e79b07..6224242c496d 100644 --- a/alg/viewshed/viewshed_executor.h +++ b/alg/viewshed/viewshed_executor.h @@ -8,23 +8,7 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #pragma once diff --git a/alg/viewshed/viewshed_types.h b/alg/viewshed/viewshed_types.h index abdaae49a2fb..3b4e9cc38625 100644 --- a/alg/viewshed/viewshed_types.h +++ b/alg/viewshed/viewshed_types.h @@ -1,25 +1,10 @@ /**************************************************************************** * (c) 2024 info@hobu.co * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ -#pragma once +#ifndef VIEWSHED_TYPES_H_INCLUDED +#define VIEWSHED_TYPES_H_INCLUDED #include #include @@ -171,3 +156,5 @@ struct Window } // namespace viewshed } // namespace gdal + +#endif diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 554ca13f1955..9e9920db5b57 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -25,15 +25,19 @@ add_library( add_dependencies(appslib generate_gdal_version_h) target_sources(${GDAL_LIB_TARGET_NAME} PRIVATE $) gdal_standard_includes(appslib) -target_compile_options(appslib PRIVATE ${GDAL_CXX_WARNING_FLAGS} ${WFLAG_OLD_STYLE_CAST}) +target_compile_options(appslib PRIVATE ${GDAL_CXX_WARNING_FLAGS} ${WFLAG_OLD_STYLE_CAST} ${WFLAG_EFFCXX}) target_include_directories( appslib PRIVATE $ $ - $ $) + $) gdal_target_link_libraries(appslib PRIVATE PROJ::proj) set_property(TARGET appslib PROPERTY POSITION_INDEPENDENT_CODE ${GDAL_OBJECT_LIBRARIES_POSITION_INDEPENDENT_CODE}) +if (GDAL_ENABLE_DRIVER_GTIFF) + target_compile_definitions(appslib PRIVATE -DHAVE_TIFF) +endif() + if (GDAL_USE_JSONC_INTERNAL) gdal_add_vendored_lib(appslib libjson) else () @@ -132,7 +136,7 @@ if (BUILD_APPS) add_dependencies(${UTILCMD} generate_gdal_version_h) target_include_directories( ${UTILCMD} PRIVATE $ $ - $ $) + $) if (MSVC) set_target_properties(${UTILCMD} PROPERTIES LINK_FLAGS "wsetargv.obj") endif () @@ -147,6 +151,11 @@ if (BUILD_APPS) target_compile_definitions(${UTILCMD} PRIVATE -DSUPPORTS_WMAIN) endif () target_link_libraries(${UTILCMD} PRIVATE $ utils_common) + + if (NOT GDAL_ENABLE_DRIVER_GTI OR GDAL_ENABLE_DRIVER_GTI_PLUGIN) + target_compile_definitions(${UTILCMD} PRIVATE -DGTI_DRIVER_DISABLED_OR_PLUGIN) + endif() + endforeach () install(TARGETS ${APPS_TARGETS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) @@ -156,8 +165,10 @@ if (BUILD_APPS) add_executable(gdaltorture EXCLUDE_FROM_ALL gdaltorture.cpp) add_executable(gdal2ogr EXCLUDE_FROM_ALL gdal2ogr.c) add_executable(gdalasyncread EXCLUDE_FROM_ALL gdalasyncread.cpp) - add_executable(gdalwarpsimple EXCLUDE_FROM_ALL gdalwarpsimple.c) add_executable(multireadtest EXCLUDE_FROM_ALL multireadtest.cpp) + if(NOT MSVC AND CMAKE_THREAD_LIBS_INIT) + target_link_libraries(multireadtest PRIVATE ${CMAKE_THREAD_LIBS_INIT}) + endif() add_executable(test_ogrsf test_ogrsf.cpp) add_executable(testreprojmulti EXCLUDE_FROM_ALL testreprojmulti.cpp) @@ -168,7 +179,6 @@ if (BUILD_APPS) gdalasyncread gdaltorture gdalflattenmask - gdalwarpsimple multireadtest test_ogrsf testreprojmulti) @@ -197,7 +207,7 @@ if (BUILD_APPS) endif () target_include_directories( ${UTILCMD} PRIVATE $ $ - $ $) + $) target_link_libraries(${UTILCMD} PRIVATE $) endforeach () endif () diff --git a/apps/argparse/argparse.hpp b/apps/argparse/argparse.hpp index a52142848192..029fa03c2c42 100644 --- a/apps/argparse/argparse.hpp +++ b/apps/argparse/argparse.hpp @@ -2086,7 +2086,7 @@ class ArgumentParser { std::stringstream stream; std::string curline("Usage: "); - curline += this->m_program_name; + curline += this->m_parser_path; const bool multiline_usage = this->m_usage_max_line_width < std::numeric_limits::max(); const size_t indent_size = curline.size(); diff --git a/apps/commonutils.cpp b/apps/commonutils.cpp index 8e0d215f22d3..3c5e3b29c7a8 100644 --- a/apps/commonutils.cpp +++ b/apps/commonutils.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2011-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "commonutils.h" diff --git a/apps/commonutils.h b/apps/commonutils.h index 6205408ce77a..4365877b6d79 100644 --- a/apps/commonutils.h +++ b/apps/commonutils.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2011-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef COMMONUTILS_H_INCLUDED diff --git a/apps/dumpoverviews.cpp b/apps/dumpoverviews.cpp index 457febbcd7fb..76f81c20a521 100644 --- a/apps/dumpoverviews.cpp +++ b/apps/dumpoverviews.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2005, Frank Warmerdam * Copyright (c) 2009-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/apps/gdal2ogr.c b/apps/gdal2ogr.c index f38378e2cdcf..75e9968a0487 100644 --- a/apps/gdal2ogr.c +++ b/apps/gdal2ogr.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2008, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" diff --git a/apps/gdal_contour.cpp b/apps/gdal_contour.cpp index 7dd5f9f9bddb..222c810435a3 100644 --- a/apps/gdal_contour.cpp +++ b/apps/gdal_contour.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2008-2013, Even Rouault * Copyright (c) 2018, Oslandia * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" @@ -155,13 +139,9 @@ GDALContourAppOptionsGetParser(GDALContourOptions *psOptions) .help(_("Generate levels on an exponential scale: base ^ k, for k an " "integer.")); - argParser->add_argument("-fl") - .metavar("") - .nargs(argparse::nargs_pattern::at_least_one) - .scan<'g', double>() - .action([psOptions](const std::string &s) - { psOptions->adfFixedLevels.push_back(CPLAtof(s.c_str())); }) - .help(_("Name one or more \"fixed levels\" to extract.")); + // Dealt manually as argparse::nargs_pattern::at_least_one is problematic + argParser->add_argument("-fl").scan<'g', double>().metavar("").help( + _("Name one or more \"fixed levels\" to extract.")); argParser->add_argument("-off") .metavar("") @@ -246,6 +226,7 @@ MAIN_START(argc, argv) if (argc < 2) { + try { GDALContourOptions sOptions; @@ -261,11 +242,54 @@ MAIN_START(argc, argv) } GDALContourOptions sOptions; + CPLStringList aosArgv; try { + /* -------------------------------------------------------------------- */ + /* Pre-processing for custom syntax that ArgumentParser does not */ + /* support. */ + /* -------------------------------------------------------------------- */ + for (int i = 1; i < argc && argv != nullptr && argv[i] != nullptr; i++) + { + // argparser is confused by arguments that have at_least_one + // cardinality, if they immediately precede positional arguments. + if (EQUAL(argv[i], "-fl") && argv[i + 1]) + { + if (strchr(argv[i + 1], ' ')) + { + const CPLStringList aosTokens( + CSLTokenizeString(argv[i + 1])); + for (const char *pszToken : aosTokens) + { + sOptions.adfFixedLevels.push_back(CPLAtof(pszToken)); + } + i += 1; + } + else + { + auto isNumeric = [](const char *pszArg) -> bool + { + char *pszEnd = nullptr; + CPLStrtod(pszArg, &pszEnd); + return pszEnd != nullptr && pszEnd[0] == '\0'; + }; + + while (i < argc - 1 && isNumeric(argv[i + 1])) + { + sOptions.adfFixedLevels.push_back(CPLAtof(argv[i + 1])); + i += 1; + } + } + } + else + { + aosArgv.AddString(argv[i]); + } + } + auto argParser = GDALContourAppOptionsGetParser(&sOptions); - argParser->parse_args_without_binary_name(argv + 1); + argParser->parse_args_without_binary_name(aosArgv.List()); if (sOptions.dfInterval == 0.0 && sOptions.adfFixedLevels.empty() && sOptions.dfExpBase == 0.0) diff --git a/apps/gdal_create.cpp b/apps/gdal_create.cpp index 9c35a7b6ed7a..45dcca410130 100644 --- a/apps/gdal_create.cpp +++ b/apps/gdal_create.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2020, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdal_footprint_bin.cpp b/apps/gdal_footprint_bin.cpp index 2e6596a7f2ca..d2e830359833 100644 --- a/apps/gdal_footprint_bin.cpp +++ b/apps/gdal_footprint_bin.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdal_footprint_lib.cpp b/apps/gdal_footprint_lib.cpp index bbf5ae51b98b..a647517bf3a7 100644 --- a/apps/gdal_footprint_lib.cpp +++ b/apps/gdal_footprint_lib.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -123,7 +107,7 @@ struct GDALFootprintOptions /*! Whether to force writing absolute paths in location field. */ bool bAbsolutePath = false; - std::string osSrcNoData; + std::string osSrcNoData{}; }; static std::unique_ptr GDALFootprintAppOptionsGetParser( @@ -295,6 +279,8 @@ class GDALFootprintMaskBand final : public GDALRasterBand { GDALRasterBand *m_poSrcBand = nullptr; + CPL_DISALLOW_COPY_ASSIGN(GDALFootprintMaskBand) + public: explicit GDALFootprintMaskBand(GDALRasterBand *poSrcBand) : m_poSrcBand(poSrcBand) @@ -1042,7 +1028,7 @@ static bool GDALFootprintProcess(GDALDataset *poSrcDS, OGRLayer *poDstLayer, CPLAssert(poGeom); if (poGeom->getGeometryType() == wkbPolygon) { - poMP->addGeometryDirectly(poGeom.release()); + poMP->addGeometry(std::move(poGeom)); } } poMemLayer = std::make_unique("", nullptr, wkbUnknown); @@ -1109,7 +1095,7 @@ static bool GDALFootprintProcess(GDALDataset *poSrcDS, OGRLayer *poDstLayer, } } if (!poNewPoly->IsEmpty()) - poMP->addGeometryDirectly(poNewPoly.release()); + poMP->addGeometry(std::move(poNewPoly)); } poGeom = std::move(poMP); } diff --git a/apps/gdal_grid_bin.cpp b/apps/gdal_grid_bin.cpp index d46a0c1756d4..8ba51a73db6a 100644 --- a/apps/gdal_grid_bin.cpp +++ b/apps/gdal_grid_bin.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdal_grid_lib.cpp b/apps/gdal_grid_lib.cpp index 1531f6d1ebca..b00640ab42e0 100644 --- a/apps/gdal_grid_lib.cpp +++ b/apps/gdal_grid_lib.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2007, Andrey Kiselev * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -116,6 +100,8 @@ struct GDALGridOptions &l_pOptions); pOptions.reset(l_pOptions); } + + CPL_DISALLOW_COPY_ASSIGN(GDALGridOptions) }; /************************************************************************/ @@ -207,6 +193,7 @@ static void PrintAlgorithmAndOptions(GDALGridAlgorithm eAlgorithm, case GGA_MetricAverageDistancePts: { const char *pszAlgName = ""; + CPL_IGNORE_RET_VAL(pszAlgName); // Make CSA happy switch (eAlgorithm) { case GGA_MetricMinimum: diff --git a/apps/gdal_rasterize_bin.cpp b/apps/gdal_rasterize_bin.cpp index 5121cfb3e27d..7dacd32669b0 100644 --- a/apps/gdal_rasterize_bin.cpp +++ b/apps/gdal_rasterize_bin.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdal_rasterize_lib.cpp b/apps/gdal_rasterize_lib.cpp index e3b7d346bb0a..2d456ffc460e 100644 --- a/apps/gdal_rasterize_lib.cpp +++ b/apps/gdal_rasterize_lib.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2005, Frank Warmerdam * Copyright (c) 2008-2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -316,14 +300,17 @@ GDALRasterizeOptionsGetParser(GDALRasterizeOptions *psOptions, .action([psOptions](const std::string &) { psOptions->bCreateOutput = true; }); + // Written that way so that in library mode, users can still use the -q + // switch, even if it has no effect + argParser->add_quiet_argument( + psOptionsForBinary ? &(psOptionsForBinary->bQuiet) : nullptr); + if (psOptionsForBinary) { argParser->add_open_options_argument( psOptionsForBinary->aosOpenOptions); - argParser->add_quiet_argument(&psOptionsForBinary->bQuiet); - argParser->add_argument("src_datasource") .metavar("") .store_into(psOptionsForBinary->osSource) @@ -379,7 +366,7 @@ static void InvertGeometries(GDALDatasetH hDstDS, double adfGeoTransform[6] = {}; GDALGetGeoTransform(hDstDS, adfGeoTransform); - OGRLinearRing *poUniverseRing = new OGRLinearRing(); + auto poUniverseRing = std::make_unique(); poUniverseRing->addPoint( adfGeoTransform[0] + -2 * adfGeoTransform[1] + -2 * adfGeoTransform[2], @@ -404,9 +391,9 @@ static void InvertGeometries(GDALDatasetH hDstDS, adfGeoTransform[0] + -2 * adfGeoTransform[1] + -2 * adfGeoTransform[2], adfGeoTransform[3] + -2 * adfGeoTransform[4] + -2 * adfGeoTransform[5]); - OGRPolygon *poUniversePoly = new OGRPolygon(); - poUniversePoly->addRingDirectly(poUniverseRing); - poInvertMP->addGeometryDirectly(poUniversePoly); + auto poUniversePoly = std::make_unique(); + poUniversePoly->addRing(std::move(poUniverseRing)); + poInvertMP->addGeometry(std::move(poUniversePoly)); bool bFoundNonPoly = false; // If we have GEOS, use it to "subtract" each polygon from the universe @@ -447,6 +434,9 @@ static void InvertGeometries(GDALDatasetH hDstDS, return; } + OGRPolygon &hUniversePoly = + *poInvertMP->getGeometryRef(poInvertMP->getNumGeometries() - 1); + /* -------------------------------------------------------------------- */ /* If we don't have GEOS, add outer rings of polygons as inner */ /* rings of poUniversePoly and inner rings as sub-polygons. Note */ @@ -473,15 +463,18 @@ static void InvertGeometries(GDALDatasetH hDstDS, } const auto ProcessPoly = - [poUniversePoly, poInvertMP](OGRPolygon *poPoly) + [&hUniversePoly, poInvertMP](OGRPolygon *poPoly) { for (int i = poPoly->getNumInteriorRings() - 1; i >= 0; --i) { - auto poNewPoly = new OGRPolygon(); - poNewPoly->addRingDirectly(poPoly->stealInteriorRing(i)); - poInvertMP->addGeometryDirectly(poNewPoly); + auto poNewPoly = std::make_unique(); + std::unique_ptr poRing( + poPoly->stealInteriorRing(i)); + poNewPoly->addRing(std::move(poRing)); + poInvertMP->addGeometry(std::move(poNewPoly)); } - poUniversePoly->addRingDirectly(poPoly->stealExteriorRing()); + std::unique_ptr poShell(poPoly->stealExteriorRing()); + hUniversePoly.addRing(std::move(poShell)); }; if (eGType == wkbPolygon) @@ -1430,10 +1423,10 @@ GDALRasterizeOptionsNew(char **papszArgv, psOptions->bCreateOutput = true; } - if (auto oTs = argParser->present("-ts")) + if (auto oTs = argParser->present>("-ts")) { - psOptions->nXSize = oTs.value(); - psOptions->nYSize = oTs.value(); + psOptions->nXSize = oTs.value()[0]; + psOptions->nYSize = oTs.value()[1]; if (psOptions->nXSize <= 0 || psOptions->nYSize <= 0) { diff --git a/apps/gdal_translate_bin.cpp b/apps/gdal_translate_bin.cpp index 71468806ba89..e51e108b1e48 100644 --- a/apps/gdal_translate_bin.cpp +++ b/apps/gdal_translate_bin.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1998, 2002, Frank Warmerdam * Copyright (c) 2007-2014, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" @@ -210,6 +194,7 @@ MAIN_START(argc, argv) else { char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS"); + const int nSubdatasets = CSLCount(papszSubdatasets) / 2; char *pszSubDest = static_cast( CPLMalloc(strlen(sOptionsForBinary.osDest.c_str()) + 32)); @@ -221,11 +206,11 @@ MAIN_START(argc, argv) CPLString osTemp; const char *pszFormat = nullptr; - if (CSLCount(papszSubdatasets) / 2 < 10) + if (nSubdatasets < 10) { pszFormat = "%s_%d"; } - else if (CSLCount(papszSubdatasets) / 2 < 100) + else if (nSubdatasets < 100) { pszFormat = "%s_%002d"; } diff --git a/apps/gdal_translate_lib.cpp b/apps/gdal_translate_lib.cpp index 79d903017568..bbd42406557c 100644 --- a/apps/gdal_translate_lib.cpp +++ b/apps/gdal_translate_lib.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2007-2015, Even Rouault * Copyright (c) 2015, Faza Mahamood * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -2737,18 +2721,11 @@ static void CopyBandInfo(GDALRasterBand *poSrcBand, GDALRasterBand *poDstBand, static int GetColorInterp(const char *pszStr) { - if (EQUAL(pszStr, "red")) - return GCI_RedBand; - if (EQUAL(pszStr, "green")) - return GCI_GreenBand; - if (EQUAL(pszStr, "blue")) - return GCI_BlueBand; - if (EQUAL(pszStr, "alpha")) - return GCI_AlphaBand; - if (EQUAL(pszStr, "gray") || EQUAL(pszStr, "grey")) - return GCI_GrayIndex; if (EQUAL(pszStr, "undefined")) return GCI_Undefined; + const int eInterp = GDALGetColorInterpretationByName(pszStr); + if (eInterp != GCI_Undefined) + return eInterp; CPLError(CE_Warning, CPLE_NotSupported, "Unsupported color interpretation: %s", pszStr); return -1; @@ -3078,7 +3055,8 @@ GDALTranslateOptionsGetParser(GDALTranslateOptions *psOptions, _("Add the indicated ground control point to the output dataset.")); argParser->add_argument("-colorinterp") - .metavar("{red|green|blue|alpha|gray|undefined},...") + .metavar("{red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|" + "swir|mwir|lwir|...},...") .action( [psOptions](const std::string &s) { @@ -3093,7 +3071,8 @@ GDALTranslateOptionsGetParser(GDALTranslateOptions *psOptions, argParser->add_argument("-colorinterp_X") .append() - .metavar("{red|green|blue|alpha|gray|undefined}") + .metavar("{red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|" + "swir|mwir|lwir|...}") .help(_("Override the color interpretation of band X.")); { @@ -3297,6 +3276,12 @@ GDALTranslateOptionsNew(char **papszArgv, psOptions->asScaleParams[nIndex].bHaveScaleSrc = false; if (i < argc - 2 && ArgIsNumeric(papszArgv[i + 1])) { + if (!ArgIsNumeric(papszArgv[i + 2])) + { + CPLError(CE_Failure, CPLE_IllegalArg, + "Value of -scale must be numeric"); + return nullptr; + } psOptions->asScaleParams[nIndex].bHaveScaleSrc = true; psOptions->asScaleParams[nIndex].dfScaleSrcMin = CPLAtofM(papszArgv[i + 1]); @@ -3308,6 +3293,12 @@ GDALTranslateOptionsNew(char **papszArgv, psOptions->asScaleParams[nIndex].bHaveScaleSrc && ArgIsNumeric(papszArgv[i + 1])) { + if (!ArgIsNumeric(papszArgv[i + 2])) + { + CPLError(CE_Failure, CPLE_IllegalArg, + "Value of -scale must be numeric"); + return nullptr; + } psOptions->asScaleParams[nIndex].dfScaleDstMin = CPLAtofM(papszArgv[i + 1]); psOptions->asScaleParams[nIndex].dfScaleDstMax = diff --git a/apps/gdal_utils.h b/apps/gdal_utils.h index a7a5b6846c77..063534a3db96 100644 --- a/apps/gdal_utils.h +++ b/apps/gdal_utils.h @@ -10,23 +10,7 @@ * Copyright (c) 2007-2015, Even Rouault * Copyright (c) 2015, Faza Mahamood * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_UTILS_H_INCLUDED diff --git a/apps/gdal_utils_priv.h b/apps/gdal_utils_priv.h index 7814c26babeb..460656b62f8d 100644 --- a/apps/gdal_utils_priv.h +++ b/apps/gdal_utils_priv.h @@ -8,23 +8,7 @@ * **************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_UTILS_PRIV_H_INCLUDED @@ -58,10 +42,10 @@ struct GDALInfoOptionsForBinary struct GDALDEMProcessingOptionsForBinary { - std::string osProcessing; - std::string osSrcFilename; - std::string osColorFilename; - std::string osDstFilename; + std::string osProcessing{}; + std::string osSrcFilename{}; + std::string osColorFilename{}; + std::string osDstFilename{}; bool bQuiet = false; }; @@ -83,7 +67,7 @@ struct GDALVectorTranslateOptionsForBinary std::string osDestDataSource{}; bool bQuiet = false; CPLStringList aosOpenOptions{}; - std::string osFormat; + std::string osFormat{}; GDALVectorTranslateAccessMode eAccessMode = ACCESS_CREATION; bool bShowUsageIfError = false; diff --git a/apps/gdal_viewshed.cpp b/apps/gdal_viewshed.cpp index c5025ee04272..e825eb95a1cf 100644 --- a/apps/gdal_viewshed.cpp +++ b/apps/gdal_viewshed.cpp @@ -6,23 +6,7 @@ * ****************************************************************************** * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/apps/gdaladdo.cpp b/apps/gdaladdo.cpp index 32d1ffa873b7..f163772f8746 100644 --- a/apps/gdaladdo.cpp +++ b/apps/gdaladdo.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2000, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" @@ -311,6 +295,17 @@ static bool PartialRefreshFromSourceTimestamp( } } } +#ifdef GTI_DRIVER_DISABLED_OR_PLUGIN + else if (poDS->GetDriver() && + EQUAL(poDS->GetDriver()->GetDescription(), "GTI")) + { + CPLError(CE_Failure, CPLE_NotSupported, + "--partial-refresh-from-source-timestamp only works on a GTI " + "dataset if the GTI driver is not built as a plugin, " + "but in core library"); + return false; + } +#else else if (auto poGTIDS = GDALDatasetCastToGTIDataset(poDS)) { regions = GTIGetSourcesMoreRecentThan(poGTIDS, sStatVRTOvr.st_mtime); @@ -320,6 +315,7 @@ static bool PartialRefreshFromSourceTimestamp( static_cast(region.nDstXSize) * region.nDstYSize; } } +#endif else { CPLError(CE_Failure, CPLE_AppDefined, diff --git a/apps/gdalargumentparser.cpp b/apps/gdalargumentparser.cpp index f9992cea7317..3b795325345b 100644 --- a/apps/gdalargumentparser.cpp +++ b/apps/gdalargumentparser.cpp @@ -6,23 +6,7 @@ * **************************************************************************** * Copyright (c) 2024, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_version_full/gdal_version.h" @@ -53,7 +37,7 @@ GDALArgumentParser::GDALArgumentParser(const std::string &program_name, [this](const auto &) { std::cout << usage() << std::endl << std::endl; - std::cout << _("Note: ") << m_program_name + std::cout << _("Note: ") << m_parser_path << _(" --long-usage for full help.") << std::endl; std::exit(0); }) diff --git a/apps/gdalargumentparser.h b/apps/gdalargumentparser.h index d72b69083f98..e6f64add7e10 100644 --- a/apps/gdalargumentparser.h +++ b/apps/gdalargumentparser.h @@ -6,23 +6,7 @@ * **************************************************************************** * Copyright (c) 2024, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDALARGUMENTPARSER_H @@ -45,8 +29,17 @@ #pragma warning(disable : 4702) #endif +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#endif + #include "argparse/argparse.hpp" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #ifdef _MSC_VER #pragma warning(pop) #endif @@ -156,7 +149,7 @@ class GDALArgumentParser : public ArgumentParser private: std::map::iterator find_argument(const std::string &name); - std::vector> aoSubparsers; + std::vector> aoSubparsers{}; std::string m_osExtraUsageHint{}; }; diff --git a/apps/gdalasyncread.cpp b/apps/gdalasyncread.cpp index 68c451931fb7..29cf12c35e78 100644 --- a/apps/gdalasyncread.cpp +++ b/apps/gdalasyncread.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2010, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_vsi.h" diff --git a/apps/gdalbuildvrt_bin.cpp b/apps/gdalbuildvrt_bin.cpp index d11ddf0cdec5..d517fbe943cc 100644 --- a/apps/gdalbuildvrt_bin.cpp +++ b/apps/gdalbuildvrt_bin.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2007-2016, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdalbuildvrt_lib.cpp b/apps/gdalbuildvrt_lib.cpp index 31e720fcc866..4d7da0545b0a 100644 --- a/apps/gdalbuildvrt_lib.cpp +++ b/apps/gdalbuildvrt_lib.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2007-2016, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ogr_api.h" @@ -254,6 +238,7 @@ class VRTBuilder bool bUseSrcMaskBand = true; bool bNoDataFromMask = false; double dfMaskValueThreshold = 0; + CPLStringList aosCreateOptions{}; /* Internal variables */ char *pszProjectionRef = nullptr; @@ -279,6 +264,8 @@ class VRTBuilder void CreateVRTSeparate(VRTDatasetH hVRTDS); void CreateVRTNonSeparate(VRTDatasetH hVRTDS); + CPL_DISALLOW_COPY_ASSIGN(VRTBuilder) + public: VRTBuilder(bool bStrictIn, const char *pszOutputFilename, int nInputFiles, const char *const *ppszInputFilenames, GDALDatasetH *pahSrcDSIn, @@ -291,7 +278,8 @@ class VRTBuilder const char *pszVRTNoData, bool bUseSrcMaskBand, bool bNoDataFromMask, double dfMaskValueThreshold, const char *pszOutputSRS, const char *pszResampling, - const char *const *papszOpenOptionsIn); + const char *const *papszOpenOptionsIn, + const CPLStringList &aosCreateOptionsIn); ~VRTBuilder(); @@ -313,8 +301,9 @@ VRTBuilder::VRTBuilder( const char *pszSrcNoDataIn, const char *pszVRTNoDataIn, bool bUseSrcMaskBandIn, bool bNoDataFromMaskIn, double dfMaskValueThresholdIn, const char *pszOutputSRSIn, - const char *pszResamplingIn, const char *const *papszOpenOptionsIn) - : bStrict(bStrictIn) + const char *pszResamplingIn, const char *const *papszOpenOptionsIn, + const CPLStringList &aosCreateOptionsIn) + : bStrict(bStrictIn), aosCreateOptions(aosCreateOptionsIn) { pszOutputFilename = CPLStrdup(pszOutputFilenameIn); nInputFiles = nInputFilesIn; @@ -1623,8 +1612,13 @@ GDALDataset *VRTBuilder::Build(GDALProgressFunc pfnProgress, return nullptr; } - VRTDatasetH hVRTDS = VRTCreate(nRasterXSize, nRasterYSize); - GDALSetDescription(hVRTDS, pszOutputFilename); + VRTDatasetH hVRTDS = cpl::down_cast( + VRTDataset::Create(pszOutputFilename, nRasterXSize, nRasterYSize, 0, + GDT_Unknown, aosCreateOptions.List())); + if (!hVRTDS) + { + return nullptr; + } if (pszOutputSRS) { @@ -1756,6 +1750,7 @@ struct GDALBuildVRTOptions std::vector anSelectedBandList{}; std::string osResampling{}; CPLStringList aosOpenOptions{}; + CPLStringList aosCreateOptions{}; bool bUseSrcMaskBand = true; bool bNoDataFromMask = false; double dfMaskValueThreshold = 0; @@ -1906,7 +1901,7 @@ GDALDatasetH GDALBuildVRT(const char *pszDest, int nSrcCount, sOptions.dfMaskValueThreshold, sOptions.osOutputSRS.empty() ? nullptr : sOptions.osOutputSRS.c_str(), sOptions.osResampling.empty() ? nullptr : sOptions.osResampling.c_str(), - sOptions.aosOpenOptions.List()); + sOptions.aosOpenOptions.List(), sOptions.aosCreateOptions); return GDALDataset::ToHandle( oBuilder.Build(sOptions.pfnProgress, sOptions.pProgressData)); @@ -2156,6 +2151,8 @@ GDALBuildVRTOptionsGetParser(GDALBuildVRTOptions *psOptions, argParser->add_open_options_argument(&psOptions->aosOpenOptions); + argParser->add_creation_options_argument(psOptions->aosCreateOptions); + argParser->add_argument("-ignore_srcmaskband") .flag() .action([psOptions](const std::string &) diff --git a/apps/gdaldem_bin.cpp b/apps/gdaldem_bin.cpp index daaa51f91863..34e5cc8bf4db 100644 --- a/apps/gdaldem_bin.cpp +++ b/apps/gdaldem_bin.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_vsi.h" diff --git a/apps/gdaldem_lib.cpp b/apps/gdaldem_lib.cpp index c42bd152ec5f..7136f84b58af 100644 --- a/apps/gdaldem_lib.cpp +++ b/apps/gdaldem_lib.cpp @@ -14,23 +14,7 @@ * http://trac.osgeo.org/gdal/ticket/2975 for more information regarding * history of this code * - * 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. + * SPDX-License-Identifier: MIT **************************************************************************** * * Slope and aspect calculations based on original method for GRASS GIS 4.1 @@ -158,7 +142,7 @@ using namespace gdal::GDALDEM; struct GDALDEMProcessingOptions { /*! output format. Use the short format name. */ - std::string osFormat; + std::string osFormat{}; /*! the progress function to use */ GDALProgressFunc pfnProgress = nullptr; @@ -184,7 +168,7 @@ struct GDALDEMProcessingOptions bool bCombined = false; bool bIgor = false; bool bMultiDirectional = false; - CPLStringList aosCreationOptions; + CPLStringList aosCreationOptions{}; int nBand = 1; }; @@ -1972,6 +1956,8 @@ class GDALColorReliefDataset : public GDALDataset int nCurBlockXOff; int nCurBlockYOff; + CPL_DISALLOW_COPY_ASSIGN(GDALColorReliefDataset) + public: GDALColorReliefDataset(GDALDatasetH hSrcDS, GDALRasterBandH hSrcBand, const char *pszColorFilename, @@ -2565,6 +2551,8 @@ template class GDALGeneric3x3Dataset : public GDALDataset int nCurLine; bool bComputeAtEdges; + CPL_DISALLOW_COPY_ASSIGN(GDALGeneric3x3Dataset) + public: GDALGeneric3x3Dataset(GDALDatasetH hSrcDS, GDALRasterBandH hSrcBand, GDALDataType eDstDataType, int bDstHasNoData, diff --git a/apps/gdalenhance.cpp b/apps/gdalenhance.cpp index d00895656417..b1a6a52734d1 100644 --- a/apps/gdalenhance.cpp +++ b/apps/gdalenhance.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2007, Frank Warmerdam * Copyright (c) 2007-2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" @@ -42,6 +26,19 @@ static int ComputeEqualizationLUTs(GDALDatasetH hDataset, int nLUTBins, double **padfScaleMax, int ***ppapanLUTs, GDALProgressFunc pfnProgress); +static CPLErr ReadLUTs(const char *pszConfigFile, int nBandCount, int nLUTBins, + int ***ppapanLUTs, double **ppadfScaleMin, + double **ppadfScaleMax); +static void WriteLUTs(int **papanLUTs, int nBandCount, int nLUTBins, + double *padfScaleMin, double *padfScaleMax, + const char *pszConfigFile); +static CPLErr WriteEnhanced(GDALDatasetH hDataset, int **papanLUTs, + int nLUTBins, double *padfScaleMin, + double *padfScaleMax, GDALDataType eOutputType, + GDALDriverH hDriver, const char *pszDest, + char **papszCreateOptions, + GDALProgressFunc pfnProgress); + static CPLErr EnhancerCallback(void *hCBData, int nXOff, int nYOff, int nXSize, int nYSize, void *pData); @@ -85,21 +82,21 @@ static void Usage() MAIN_START(argc, argv) { - GDALDatasetH hDataset, hOutDS; - int i; + GDALDatasetH hDataset = nullptr; const char *pszSource = nullptr, *pszDest = nullptr, *pszFormat = nullptr; GDALDriverH hDriver = nullptr; GDALDataType eOutputType = GDT_Unknown; char **papszCreateOptions = nullptr; GDALProgressFunc pfnProgress = GDALTermProgress; + int nBandCount = 0; int nLUTBins = 256; const char *pszMethod = "minmax"; // double dfStdDevMult = 0.0; double *padfScaleMin = nullptr; double *padfScaleMax = nullptr; int **papanLUTs = nullptr; - int iBand; const char *pszConfigFile = nullptr; + int nRetCode = 0; /* Check strict compilation and runtime library version as we use C++ API */ if (!GDAL_CHECK_VERSION(argv[0])) @@ -111,19 +108,22 @@ MAIN_START(argc, argv) GDALAllRegister(); argc = GDALGeneralCmdLineProcessor(argc, &argv, 0); if (argc < 1) - exit(-argc); + { + GDALDestroyDriverManager(); + exit(0); + } /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ - for (i = 1; i < argc; i++) + for (int i = 1; i < argc; i++) { if (EQUAL(argv[i], "--utility_version")) { printf("%s was compiled against GDAL %s and is running against " "GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); - return 0; + goto exit; } else if (EQUAL(argv[i], "--help")) { @@ -137,9 +137,7 @@ MAIN_START(argc, argv) else if (i < argc - 1 && EQUAL(argv[i], "-ot")) { - int iType; - - for (iType = 1; iType < GDT_TypeCount; iType++) + for (int iType = 1; iType < GDT_TypeCount; iType++) { if (GDALGetDataTypeName(static_cast(iType)) != nullptr && @@ -232,57 +230,60 @@ MAIN_START(argc, argv) { fprintf(stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg()); - GDALDestroyDriverManager(); - exit(1); + goto exit; } - int nBandCount = GDALGetRasterCount(hDataset); + nBandCount = GDALGetRasterCount(hDataset); /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ - CPLString osFormat; - if (pszFormat == nullptr && pszDest != nullptr) { - osFormat = GetOutputDriverForRaster(pszDest); - if (osFormat.empty()) + CPLString osFormat; + if (pszFormat == nullptr && pszDest != nullptr) { - GDALDestroyDriverManager(); - exit(1); + osFormat = GetOutputDriverForRaster(pszDest); + if (osFormat.empty()) + { + GDALDestroyDriverManager(); + exit(1); + } } - } - else if (pszFormat != nullptr) - { - osFormat = pszFormat; - } - - if (!osFormat.empty()) - { - hDriver = GDALGetDriverByName(osFormat); - if (hDriver == nullptr) + else if (pszFormat != nullptr) { - int iDr; + osFormat = pszFormat; + } - printf("Output driver `%s' not recognised.\n", osFormat.c_str()); - printf("The following format drivers are configured and support " - "output:\n"); - for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) + if (!osFormat.empty()) + { + hDriver = GDALGetDriverByName(osFormat); + if (hDriver == nullptr) { - hDriver = GDALGetDriver(iDr); - - if (GDALGetMetadataItem(hDriver, GDAL_DCAP_RASTER, nullptr) != - nullptr && - (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, nullptr) != - nullptr || - GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, - nullptr) != nullptr)) + int iDr; + + printf("Output driver `%s' not recognised.\n", + osFormat.c_str()); + printf( + "The following format drivers are configured and support " + "output:\n"); + for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) { - printf(" %s: %s\n", GDALGetDriverShortName(hDriver), - GDALGetDriverLongName(hDriver)); + hDriver = GDALGetDriver(iDr); + + if (GDALGetMetadataItem(hDriver, GDAL_DCAP_RASTER, + nullptr) != nullptr && + (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, + nullptr) != nullptr || + GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, + nullptr) != nullptr)) + { + printf(" %s: %s\n", GDALGetDriverShortName(hDriver), + GDALGetDriverLongName(hDriver)); + } } + printf("\n"); + goto exit; } - printf("\n"); - Usage(); } } @@ -301,205 +302,61 @@ MAIN_START(argc, argv) /* -------------------------------------------------------------------- */ else if (pszConfigFile != nullptr) { - char **papszLines = CSLLoad(pszConfigFile); - if (CSLCount(papszLines) == 0) - exit(1); - - if (CSLCount(papszLines) != nBandCount) + if (ReadLUTs(pszConfigFile, nBandCount, nLUTBins, &papanLUTs, + &padfScaleMin, &padfScaleMax) != CE_None) { - fprintf(stderr, - "Did not get %d lines in config file as expected.\n", - nBandCount); - exit(1); - } - - padfScaleMin = - static_cast(CPLCalloc(nBandCount, sizeof(double))); - padfScaleMax = - static_cast(CPLCalloc(nBandCount, sizeof(double))); - - for (iBand = 0; iBand < nBandCount; iBand++) - { - int iLUT; - char **papszTokens = CSLTokenizeString(papszLines[iBand]); - - if (CSLCount(papszTokens) < 3 || atoi(papszTokens[0]) != iBand + 1) - { - fprintf(stderr, "Line %d seems to be corrupt.\n", iBand + 1); - exit(1); - } - - // Process scale min/max - - padfScaleMin[iBand] = CPLAtof(papszTokens[1]); - padfScaleMax[iBand] = CPLAtof(papszTokens[2]); - - if (CSLCount(papszTokens) == 3) - continue; - - // process lut - if (papanLUTs == nullptr) - { - nLUTBins = CSLCount(papszTokens) - 3; - papanLUTs = - static_cast(CPLCalloc(sizeof(int *), nBandCount)); - } - - papanLUTs[iBand] = - static_cast(CPLCalloc(nLUTBins, sizeof(int))); - - for (iLUT = 0; iLUT < nLUTBins; iLUT++) - papanLUTs[iBand][iLUT] = atoi(papszTokens[iLUT + 3]); - - CSLDestroy(papszTokens); + nRetCode = 1; + goto exit; } } - /* -------------------------------------------------------------------- */ - /* If there is no destination, just report the scaling values */ - /* and luts. */ - /* -------------------------------------------------------------------- */ - if (pszDest == nullptr) - { - FILE *fpConfig = stdout; - if (pszConfigFile) - fpConfig = fopen(pszConfigFile, "w"); - - for (iBand = 0; iBand < nBandCount; iBand++) - { - fprintf(fpConfig, "%d:Band ", iBand + 1); - if (padfScaleMin != nullptr) - fprintf(fpConfig, "%g:ScaleMin %g:ScaleMax ", - padfScaleMin[iBand], padfScaleMax[iBand]); - - if (papanLUTs) - { - int iLUT; - - for (iLUT = 0; iLUT < nLUTBins; iLUT++) - fprintf(fpConfig, "%d ", papanLUTs[iBand][iLUT]); - } - fprintf(fpConfig, "\n"); - } - - if (pszConfigFile) - fclose(fpConfig); - - exit(0); - } - if (padfScaleMin == nullptr || padfScaleMax == nullptr) { fprintf(stderr, "-equalize or -config filename command line options " "must be specified.\n"); - exit(1); + Usage(); } - /* ==================================================================== */ - /* Create a virtual dataset. */ - /* ==================================================================== */ - EnhanceCBInfo *pasEInfo = static_cast( - CPLCalloc(nBandCount, sizeof(EnhanceCBInfo))); - /* -------------------------------------------------------------------- */ - /* Make a virtual clone. */ + /* If there is no destination, just report the scaling values */ + /* and luts. */ /* -------------------------------------------------------------------- */ - VRTDataset *poVDS = new VRTDataset(GDALGetRasterXSize(hDataset), - GDALGetRasterYSize(hDataset)); - - if (GDALGetGCPCount(hDataset) == 0) + if (pszDest == nullptr) { - double adfGeoTransform[6]; - - const char *pszProjection = GDALGetProjectionRef(hDataset); - if (pszProjection != nullptr && strlen(pszProjection) > 0) - poVDS->SetProjection(pszProjection); - - if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None) - poVDS->SetGeoTransform(adfGeoTransform); + WriteLUTs(papanLUTs, nBandCount, nLUTBins, padfScaleMin, padfScaleMax, + pszConfigFile); } else { - poVDS->SetGCPs(GDALGetGCPCount(hDataset), GDALGetGCPs(hDataset), - GDALGetGCPProjection(hDataset)); - } - - poVDS->SetMetadata(static_cast(hDataset)->GetMetadata()); - - for (iBand = 0; iBand < nBandCount; iBand++) - { - VRTSourcedRasterBand *poVRTBand; - GDALRasterBand *poSrcBand; - GDALDataType eBandType; - - poSrcBand = - static_cast(hDataset)->GetRasterBand(iBand + 1); - - /* -------------------------------------------------------------------- - */ - /* Select output data type to match source. */ - /* -------------------------------------------------------------------- - */ - if (eOutputType == GDT_Unknown) - eBandType = GDT_Byte; - else - eBandType = eOutputType; - - /* -------------------------------------------------------------------- - */ - /* Create this band. */ - /* -------------------------------------------------------------------- - */ - poVDS->AddBand(eBandType, nullptr); - poVRTBand = cpl::down_cast( - poVDS->GetRasterBand(iBand + 1)); - - /* -------------------------------------------------------------------- - */ - /* Create a function based source with info on how to apply the */ - /* enhancement. */ - /* -------------------------------------------------------------------- - */ - pasEInfo[iBand].poSrcBand = poSrcBand; - pasEInfo[iBand].eWrkType = eBandType; - pasEInfo[iBand].dfScaleMin = padfScaleMin[iBand]; - pasEInfo[iBand].dfScaleMax = padfScaleMax[iBand]; - pasEInfo[iBand].nLUTBins = nLUTBins; - - if (papanLUTs) - pasEInfo[iBand].panLUT = papanLUTs[iBand]; - - poVRTBand->AddFuncSource(EnhancerCallback, pasEInfo + iBand); - - /* -------------------------------------------------------------------- - */ - /* copy over some other information of interest. */ - /* -------------------------------------------------------------------- - */ - poVRTBand->CopyCommonInfoFrom(poSrcBand); + if (WriteEnhanced(hDataset, papanLUTs, nLUTBins, padfScaleMin, + padfScaleMax, eOutputType, hDriver, pszDest, + papszCreateOptions, pfnProgress) != CE_None) + { + nRetCode = 1; + } } - /* -------------------------------------------------------------------- */ - /* Write to the output file using CopyCreate(). */ - /* -------------------------------------------------------------------- */ - hOutDS = GDALCreateCopy(hDriver, pszDest, static_cast(poVDS), - FALSE, papszCreateOptions, pfnProgress, nullptr); - if (hOutDS != nullptr) - GDALClose(hOutDS); - - GDALClose(poVDS); - - GDALClose(hDataset); - /* -------------------------------------------------------------------- */ /* Cleanup and exit. */ /* -------------------------------------------------------------------- */ +exit: + GDALClose(hDataset); GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); + if (papanLUTs) + { + for (int iBand = 0; iBand < nBandCount; iBand++) + { + CPLFree(papanLUTs[iBand]); + } + CPLFree(papanLUTs); + } + CPLFree(padfScaleMin); + CPLFree(padfScaleMax); - exit(0); + exit(nRetCode); } MAIN_END @@ -517,10 +374,7 @@ static int ComputeEqualizationLUTs(GDALDatasetH hDataset, int nLUTBins, GDALProgressFunc pfnProgress) { - int iBand; int nBandCount = GDALGetRasterCount(hDataset); - int nHistSize = 0; - GUIntBig *panHistogram = nullptr; // For now we always compute min/max *ppadfScaleMin = @@ -533,17 +387,16 @@ static int ComputeEqualizationLUTs(GDALDatasetH hDataset, int nLUTBins, /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ - for (iBand = 0; iBand < nBandCount; iBand++) + for (int iBand = 0; iBand < nBandCount; iBand++) { GDALRasterBandH hBand = GDALGetRasterBand(hDataset, iBand + 1); - CPLErr eErr; - - /* -------------------------------------------------------------------- - */ - /* Get a reasonable histogram. */ - /* -------------------------------------------------------------------- - */ - eErr = GDALGetDefaultHistogramEx( + GUIntBig *panHistogram = nullptr; + int nHistSize = 0; + + /* ----------------------------------------------------------------- */ + /* Get a reasonable histogram. */ + /* ----------------------------------------------------------------- */ + CPLErr eErr = GDALGetDefaultHistogramEx( hBand, *ppadfScaleMin + iBand, *ppadfScaleMax + iBand, &nHistSize, &panHistogram, TRUE, pfnProgress, nullptr); @@ -553,19 +406,16 @@ static int ComputeEqualizationLUTs(GDALDatasetH hDataset, int nLUTBins, panHistogram[0] = 0; // zero out extremes (nodata, etc) panHistogram[nHistSize - 1] = 0; - /* -------------------------------------------------------------------- - */ - /* Total histogram count, and build cumulative histogram. */ + /* ----------------------------------------------------------------- */ + /* Total histogram count, and build cumulative histogram. */ /* We take care to use big integers as there may be more than 4 */ - /* Gigapixels. */ - /* -------------------------------------------------------------------- - */ + /* Gigapixels. */ + /* ----------------------------------------------------------------- */ GUIntBig *panCumHist = static_cast(CPLCalloc(sizeof(GUIntBig), nHistSize)); GUIntBig nTotal = 0; - int iHist; - for (iHist = 0; iHist < nHistSize; iHist++) + for (int iHist = 0; iHist < nHistSize; iHist++) { panCumHist[iHist] = nTotal + panHistogram[iHist] / 2; nTotal += panHistogram[iHist]; @@ -581,17 +431,14 @@ static int ComputeEqualizationLUTs(GDALDatasetH hDataset, int nLUTBins, nTotal = 1; } - /* -------------------------------------------------------------------- - */ - /* Now compute a LUT from the cumulative histogram. */ - /* -------------------------------------------------------------------- - */ + /* ----------------------------------------------------------------- */ + /* Now compute a LUT from the cumulative histogram. */ + /* ----------------------------------------------------------------- */ int *panLUT = static_cast(CPLCalloc(sizeof(int), nLUTBins)); - int iLUT; - for (iLUT = 0; iLUT < nLUTBins; iLUT++) + for (int iLUT = 0; iLUT < nLUTBins; iLUT++) { - iHist = (iLUT * nHistSize) / nLUTBins; + int iHist = (iLUT * nHistSize) / nLUTBins; int nValue = static_cast((panCumHist[iHist] * nLUTBins) / nTotal); @@ -622,17 +469,16 @@ static CPLErr EnhancerCallback(void *hCBData, int nXOff, int nYOff, int nXSize, { CPLError(CE_Failure, CPLE_AppDefined, "Currently gdalenhance only supports Byte output."); - exit(2); + return CE_Failure; } GByte *pabyOutImage = static_cast(pData); - CPLErr eErr; float *pafSrcImage = static_cast( CPLCalloc(sizeof(float), static_cast(nXSize) * nYSize)); - eErr = psEInfo->poSrcBand->RasterIO(GF_Read, nXOff, nYOff, nXSize, nYSize, - pafSrcImage, nXSize, nYSize, - GDT_Float32, 0, 0, nullptr); + CPLErr eErr = psEInfo->poSrcBand->RasterIO( + GF_Read, nXOff, nYOff, nXSize, nYSize, pafSrcImage, nXSize, nYSize, + GDT_Float32, 0, 0, nullptr); if (eErr != CE_None) { @@ -641,14 +487,13 @@ static CPLErr EnhancerCallback(void *hCBData, int nXOff, int nYOff, int nXSize, } int nPixelCount = nXSize * nYSize; - int iPixel; int bHaveNoData; float fNoData = static_cast(psEInfo->poSrcBand->GetNoDataValue(&bHaveNoData)); double dfScale = psEInfo->nLUTBins / (psEInfo->dfScaleMax - psEInfo->dfScaleMin); - for (iPixel = 0; iPixel < nPixelCount; iPixel++) + for (int iPixel = 0; iPixel < nPixelCount; iPixel++) { if (bHaveNoData && pafSrcImage[iPixel] == fNoData) { @@ -670,3 +515,198 @@ static CPLErr EnhancerCallback(void *hCBData, int nXOff, int nYOff, int nXSize, return CE_None; } + +/************************************************************************/ +/* ReadLUTs() */ +/* */ +/* Read a LUT for each band from a file. */ +/************************************************************************/ + +CPLErr ReadLUTs(const char *pszConfigFile, int nBandCount, int nLUTBins, + int ***ppapanLUTs, double **ppadfScaleMin, + double **ppadfScaleMax) +{ + const CPLStringList aosLines(CSLLoad(pszConfigFile)); + + if (aosLines.size() != nBandCount) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Did not get %d lines in config file as expected.\n", + nBandCount); + return CE_Failure; + } + + *ppadfScaleMin = + static_cast(CPLCalloc(nBandCount, sizeof(double))); + *ppadfScaleMax = + static_cast(CPLCalloc(nBandCount, sizeof(double))); + *ppapanLUTs = static_cast(CPLCalloc(sizeof(int *), nBandCount)); + + for (int iBand = 0; iBand < nBandCount; iBand++) + { + const CPLStringList aosTokens(CSLTokenizeString(aosLines[iBand])); + + if (aosTokens.size() < (nLUTBins + 3) || + atoi(aosTokens[0]) != iBand + 1) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Line %d seems to be corrupt.\n", iBand + 1); + return CE_Failure; + } + + // Process scale min/max + + (*ppadfScaleMin)[iBand] = CPLAtof(aosTokens[1]); + (*ppadfScaleMax)[iBand] = CPLAtof(aosTokens[2]); + + // process lut + + (*ppapanLUTs)[iBand] = + static_cast(CPLCalloc(nLUTBins, sizeof(int))); + + for (int iLUT = 0; iLUT < nLUTBins; iLUT++) + (*ppapanLUTs)[iBand][iLUT] = atoi(aosTokens[iLUT + 3]); + } + + return CE_None; +} + +/************************************************************************/ +/* WriteLUTs() */ +/* */ +/* Write the LUT for each band to a file or stdout. */ +/************************************************************************/ + +void WriteLUTs(int **papanLUTs, int nBandCount, int nLUTBins, + double *padfScaleMin, double *padfScaleMax, + const char *pszConfigFile) +{ + FILE *fpConfig = stdout; + if (pszConfigFile) + fpConfig = fopen(pszConfigFile, "w"); + + for (int iBand = 0; iBand < nBandCount; iBand++) + { + fprintf(fpConfig, "%d:Band ", iBand + 1); + fprintf(fpConfig, "%g:ScaleMin %g:ScaleMax ", padfScaleMin[iBand], + padfScaleMax[iBand]); + + if (papanLUTs) + { + for (int iLUT = 0; iLUT < nLUTBins; iLUT++) + fprintf(fpConfig, "%d ", papanLUTs[iBand][iLUT]); + } + fprintf(fpConfig, "\n"); + } + + if (pszConfigFile) + fclose(fpConfig); +} + +/************************************************************************/ +/* WriteEnhanced() */ +/* */ +/* Write an enhanced image using the provided LUTs. */ +/************************************************************************/ + +CPLErr WriteEnhanced(GDALDatasetH hDataset, int **papanLUTs, int nLUTBins, + double *padfScaleMin, double *padfScaleMax, + GDALDataType eOutputType, GDALDriverH hDriver, + const char *pszDest, char **papszCreateOptions, + GDALProgressFunc pfnProgress) +{ + int nBandCount = GDALGetRasterCount(hDataset); + + EnhanceCBInfo *pasEInfo = static_cast( + CPLCalloc(nBandCount, sizeof(EnhanceCBInfo))); + + /* -------------------------------------------------------------------- */ + /* Make a virtual clone. */ + /* -pixe------------------------------------------------------------------- */ + VRTDataset *poVDS = new VRTDataset(GDALGetRasterXSize(hDataset), + GDALGetRasterYSize(hDataset)); + + if (GDALGetGCPCount(hDataset) == 0) + { + double adfGeoTransform[6]; + + const char *pszProjection = GDALGetProjectionRef(hDataset); + if (pszProjection != nullptr && strlen(pszProjection) > 0) + poVDS->SetProjection(pszProjection); + + if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None) + poVDS->SetGeoTransform(adfGeoTransform); + } + else + { + poVDS->SetGCPs(GDALGetGCPCount(hDataset), GDALGetGCPs(hDataset), + GDALGetGCPProjection(hDataset)); + } + + poVDS->SetMetadata(GDALDataset::FromHandle(hDataset)->GetMetadata()); + + for (int iBand = 0; iBand < nBandCount; iBand++) + { + VRTSourcedRasterBand *poVRTBand; + GDALRasterBand *poSrcBand; + GDALDataType eBandType; + + poSrcBand = GDALDataset::FromHandle(hDataset)->GetRasterBand(iBand + 1); + + /* ---------------------------------------------------------------- */ + /* Select output data type to match source. */ + /* ---------------------------------------------------------------- */ + if (eOutputType == GDT_Unknown) + eBandType = GDT_Byte; + else + eBandType = eOutputType; + + /* ---------------------------------------------------------------- */ + /* Create this band. */ + /* ---------------------------------------------------------------- */ + poVDS->AddBand(eBandType, nullptr); + poVRTBand = cpl::down_cast( + poVDS->GetRasterBand(iBand + 1)); + + /* ---------------------------------------------------------------- */ + /* Create a function based source with info on how to apply the */ + /* enhancement. */ + /* ---------------------------------------------------------------- */ + pasEInfo[iBand].poSrcBand = poSrcBand; + pasEInfo[iBand].eWrkType = eBandType; + pasEInfo[iBand].dfScaleMin = padfScaleMin[iBand]; + pasEInfo[iBand].dfScaleMax = padfScaleMax[iBand]; + pasEInfo[iBand].nLUTBins = nLUTBins; + + if (papanLUTs) + pasEInfo[iBand].panLUT = papanLUTs[iBand]; + + poVRTBand->AddFuncSource(EnhancerCallback, pasEInfo + iBand); + + /* ---------------------------------------------------------------- */ + /* copy over some other information of interest. */ + /* ---------------------------------------------------------------- */ + poVRTBand->CopyCommonInfoFrom(poSrcBand); + } + + /* -------------------------------------------------------------------- */ + /* Write to the output file using CopyCreate(). */ + /* -------------------------------------------------------------------- */ + GDALDatasetH hOutDS = + GDALCreateCopy(hDriver, pszDest, static_cast(poVDS), + FALSE, papszCreateOptions, pfnProgress, nullptr); + CPLErr eErr = CE_None; + if (hOutDS == nullptr) + { + eErr = CE_Failure; + } + else + { + GDALClose(hOutDS); + } + + GDALClose(poVDS); + CPLFree(pasEInfo); + + return eErr; +} diff --git a/apps/gdalflattenmask.c b/apps/gdalflattenmask.c index 37a52f27cc5a..ef0ff92e15fc 100644 --- a/apps/gdalflattenmask.c +++ b/apps/gdalflattenmask.c @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2008-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" diff --git a/apps/gdalinfo_bin.cpp b/apps/gdalinfo_bin.cpp index 0a72c73a35d4..71ab9024d1a5 100644 --- a/apps/gdalinfo_bin.cpp +++ b/apps/gdalinfo_bin.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1998, Frank Warmerdam * Copyright (c) 2007-2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_version.h" @@ -92,6 +76,11 @@ MAIN_START(argc, argv) GDALInfoOptionsForBinary sOptionsForBinary; + if (CSLFindString(argv, "-stdout") < 0) + { + argv = CSLAddString(argv, "-stdout"); + } + std::unique_ptr psOptions{ GDALInfoOptionsNew(argv + 1, &sOptionsForBinary), GDALInfoOptionsFree}; CSLDestroy(argv); @@ -201,7 +190,7 @@ MAIN_START(argc, argv) if (sOptionsForBinary.nSubdataset > 0) { char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS"); - int nSubdatasets = CSLCount(papszSubdatasets); + const int nSubdatasets = CSLCount(papszSubdatasets) / 2; if (nSubdatasets > 0 && sOptionsForBinary.nSubdataset <= nSubdatasets) diff --git a/apps/gdalinfo_lib.cpp b/apps/gdalinfo_lib.cpp index 293bdbbf66d2..502a748a7281 100644 --- a/apps/gdalinfo_lib.cpp +++ b/apps/gdalinfo_lib.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2007-2015, Even Rouault * Copyright (c) 2015, Faza Mahamood * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -58,7 +42,8 @@ #include "ogr_api.h" #include "ogr_srs_api.h" #include "ogr_spatialref.h" -#include "ogrgeojsonreader.h" +#include "ogrlibjsonutils.h" +#include "ogrgeojsongeometry.h" #include "ogrgeojsonwriter.h" using std::vector; @@ -135,7 +120,7 @@ struct GDALInfoOptions /*! report metadata for the specified domains. "all" can be used to report metadata in all domains. */ - CPLStringList aosExtraMDDomains; + CPLStringList aosExtraMDDomains{}; /*! WKT format used for SRS */ std::string osWKTFormat = "WKT2"; @@ -1128,25 +1113,21 @@ char *GDALInfo(GDALDatasetH hDataset, const GDALInfoOptions *psOptions) json_object_object_add(poStacEOBand, "name", poBandName); } - if (GDALGetDescription(hBand) != nullptr && - strlen(GDALGetDescription(hBand)) > 0) + const char *pszBandDesc = GDALGetDescription(hBand); + if (pszBandDesc != nullptr && strlen(pszBandDesc) > 0) { if (bJson) { - json_object *poBandDescription = - json_object_new_string(GDALGetDescription(hBand)); json_object_object_add(poBand, "description", - poBandDescription); + json_object_new_string(pszBandDesc)); - json_object *poStacBandDescription = - json_object_new_string(GDALGetDescription(hBand)); json_object_object_add(poStacEOBand, "description", - poStacBandDescription); + json_object_new_string(pszBandDesc)); } else { Concat(osStr, psOptions->bStdoutOutput, " Description = %s\n", - GDALGetDescription(hBand)); + pszBandDesc); } } else @@ -1161,6 +1142,17 @@ char *GDALInfo(GDALDatasetH hDataset, const GDALInfoOptions *psOptions) } } + if (bJson) + { + const char *pszCommonName = GDALGetSTACCommonNameFromColorInterp( + GDALGetRasterColorInterpretation(hBand)); + if (pszCommonName) + { + json_object_object_add(poStacEOBand, "common_name", + json_object_new_string(pszCommonName)); + } + } + { int bGotMin = FALSE; int bGotMax = FALSE; @@ -2269,6 +2261,9 @@ static void GDALInfoReportMetadata(const GDALInfoOptions *psOptions, GDALInfoPrintMetadata(psOptions, hObject, "RPC", "RPC Metadata", pszIndent, bJson, poMetadata, osStr); } + + GDALInfoPrintMetadata(psOptions, hObject, "IMAGERY", "Imagery", pszIndent, + bJson, poMetadata, osStr); } /************************************************************************/ diff --git a/apps/gdallocationinfo.cpp b/apps/gdallocationinfo.cpp index 13613475e98d..bcd6e5225141 100644 --- a/apps/gdallocationinfo.cpp +++ b/apps/gdallocationinfo.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2010, Frank Warmerdam * Copyright (c) 2010-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" @@ -42,12 +26,6 @@ #include -#ifdef _WIN32 -#include -#else -#include -#endif - /************************************************************************/ /* GetSRSAsWKT */ /************************************************************************/ @@ -316,7 +294,7 @@ MAIN_START(argc, argv) if (std::isnan(dfGeoX)) { // Is it an interactive terminal ? - if (isatty(static_cast(fileno(stdin)))) + if (CPLIsInteractive(stdin)) { if (!osSourceSRS.empty()) { diff --git a/apps/gdalmanage.cpp b/apps/gdalmanage.cpp index 46f965cb3809..80710813bc09 100644 --- a/apps/gdalmanage.cpp +++ b/apps/gdalmanage.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2007, Frank Warmerdam * Copyright (c) 2008-2009, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdalmdiminfo_bin.cpp b/apps/gdalmdiminfo_bin.cpp index 216eeb97bef0..a79fcfa3d46d 100644 --- a/apps/gdalmdiminfo_bin.cpp +++ b/apps/gdalmdiminfo_bin.cpp @@ -7,23 +7,7 @@ * **************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_version.h" diff --git a/apps/gdalmdiminfo_lib.cpp b/apps/gdalmdiminfo_lib.cpp index 0502cc4d090f..cf59e16d4dd4 100644 --- a/apps/gdalmdiminfo_lib.cpp +++ b/apps/gdalmdiminfo_lib.cpp @@ -7,23 +7,7 @@ * **************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/gdalmdimtranslate_bin.cpp b/apps/gdalmdimtranslate_bin.cpp index 65843abea938..ee2ea18986e4 100644 --- a/apps/gdalmdimtranslate_bin.cpp +++ b/apps/gdalmdimtranslate_bin.cpp @@ -7,23 +7,7 @@ * **************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdalmdimtranslate_lib.cpp b/apps/gdalmdimtranslate_lib.cpp index 7895b5a39076..02d189c277eb 100644 --- a/apps/gdalmdimtranslate_lib.cpp +++ b/apps/gdalmdimtranslate_lib.cpp @@ -7,23 +7,7 @@ * **************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/gdalsrsinfo.cpp b/apps/gdalsrsinfo.cpp index 05882a7ab205..4b9afdc4d89a 100644 --- a/apps/gdalsrsinfo.cpp +++ b/apps/gdalsrsinfo.cpp @@ -10,23 +10,7 @@ * Copyright (c) 1998, Frank Warmerdam * Copyright (c) 2011-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdaltindex_bin.cpp b/apps/gdaltindex_bin.cpp index 3d14d61e3ac2..9c57b20d9640 100644 --- a/apps/gdaltindex_bin.cpp +++ b/apps/gdaltindex_bin.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2001, Frank Warmerdam, DM Solutions Group Inc * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdaltindex_lib.cpp b/apps/gdaltindex_lib.cpp index 7101a7d6ba0b..b49445bb3b5f 100644 --- a/apps/gdaltindex_lib.cpp +++ b/apps/gdaltindex_lib.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2001, Frank Warmerdam, DM Solutions Group Inc * Copyright (c) 2007-2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -291,6 +275,11 @@ static std::unique_ptr GDALTileIndexAppOptionsGetParser( .scan<'g', double>() .help(_("Set target extent in SRS unit.")); + argParser->add_argument("-ot") + .metavar("") + .store_into(psOptions->osDataType) + .help(_("Output data type.")); + argParser->add_argument("-bandcount") .metavar("") .store_into(psOptions->osBandCount) @@ -387,6 +376,8 @@ struct GDALTileIndexTileIterator int iCurSrc = 0; VSIDIR *psDir = nullptr; + CPL_DISALLOW_COPY_ASSIGN(GDALTileIndexTileIterator) + GDALTileIndexTileIterator(const GDALTileIndexOptions *psOptionsIn, int nSrcCountIn, const char *const *papszSrcDSNamesIn) @@ -1283,7 +1274,7 @@ GDALDatasetH GDALTileIndex(const char *pszDest, int nSrcCount, auto poRing = std::make_unique(); for (int k = 0; k < 5; k++) poRing->addPoint(adfX[k], adfY[k]); - poPoly->addRingDirectly(poRing.release()); + poPoly->addRing(std::move(poRing)); poFeature->SetGeometryDirectly(poPoly.release()); if (poLayer->CreateFeature(poFeature.get()) != OGRERR_NONE) diff --git a/apps/gdaltorture.cpp b/apps/gdaltorture.cpp index 38109719310e..fa7fbb6aee2e 100644 --- a/apps/gdaltorture.cpp +++ b/apps/gdaltorture.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2008-2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" diff --git a/apps/gdaltransform.cpp b/apps/gdaltransform.cpp index 7dea9f3bbb48..7b77da3dd10e 100644 --- a/apps/gdaltransform.cpp +++ b/apps/gdaltransform.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2007, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -40,19 +24,12 @@ #include "gdal_alg.h" #include "gdalwarper.h" #include "gdal.h" -#include "gdal_version.h" #include "ogr_api.h" #include "ogr_core.h" #include "ogr_spatialref.h" #include "ogr_srs_api.h" #include "commonutils.h" -#ifdef _WIN32 -#include -#else -#include -#endif - /************************************************************************/ /* Usage() */ /************************************************************************/ @@ -376,7 +353,7 @@ MAIN_START(argc, argv) if (!bCoordOnCommandLine) { // Is it an interactive terminal ? - if (isatty(static_cast(fileno(stdin)))) + if (CPLIsInteractive(stdin)) { if (pszSrcFilename != nullptr) { @@ -402,6 +379,11 @@ MAIN_START(argc, argv) if (fgets(szLine, sizeof(szLine) - 1, stdin) == nullptr) break; + size_t nLen = strlen(szLine); + if (nLen && szLine[nLen - 1] == '\n') + szLine[--nLen] = 0; + if (nLen && szLine[nLen - 1] == '\r') + szLine[--nLen] = 0; const CPLStringList aosTokens(CSLTokenizeString(szLine)); const int nCount = aosTokens.size(); diff --git a/apps/gdalwarp_bin.cpp b/apps/gdalwarp_bin.cpp index a674e6de360a..29c168a352c2 100644 --- a/apps/gdalwarp_bin.cpp +++ b/apps/gdalwarp_bin.cpp @@ -9,23 +9,7 @@ * Fort Collin, CO * Copyright (c) 2007-2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/gdalwarp_lib.cpp b/apps/gdalwarp_lib.cpp index 7e43acdce3ad..737a161f96b7 100644 --- a/apps/gdalwarp_lib.cpp +++ b/apps/gdalwarp_lib.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2007-2015, Even Rouault * Copyright (c) 2015, Faza Mahamood * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -1120,6 +1104,8 @@ static bool CanUseBuildVRT(int nSrcCount, GDALDatasetH *pahSrcDS) return bCanUseBuildVRT; } +#ifdef HAVE_TIFF + /************************************************************************/ /* DealWithCOGOptions() */ /************************************************************************/ @@ -1175,8 +1161,8 @@ static bool DealWithCOGOptions(CPLStringList &aosCreateOptions, int nSrcCount, GDALWarpAppOptions oClonedOptions(*psOptions); oClonedOptions.bQuiet = true; - CPLString osTmpFilename; - osTmpFilename.Printf("/vsimem/gdalwarp/%p.tif", &oClonedOptions); + const CPLString osTmpFilename( + VSIMemGenerateHiddenFilename("gdalwarp_tmp.tif")); CPLStringList aosTmpGTiffCreateOptions; aosTmpGTiffCreateOptions.SetNameValue("SPARSE_OK", "YES"); aosTmpGTiffCreateOptions.SetNameValue("TILED", "YES"); @@ -1224,6 +1210,8 @@ static bool DealWithCOGOptions(CPLStringList &aosCreateOptions, int nSrcCount, return bRet; } +#endif + /************************************************************************/ /* GDALWarpIndirect() */ /************************************************************************/ @@ -1289,11 +1277,14 @@ static GDALDatasetH GDALWarpIndirect(const char *pszDest, GDALDriverH hDriver, if ((nBands == 1 || (nBands > 1 && GDALGetRasterColorInterpretation(GDALGetRasterBand( pahSrcDS[0], nBands)) != GCI_AlphaBand)) && - (psOptions->bEnableDstAlpha || - (EQUAL(psOptions->osFormat.c_str(), "COG") && - COGHasWarpingOptions(aosCreateOptions.List()) && - CPLTestBool( - aosCreateOptions.FetchNameValueDef("ADD_ALPHA", "YES"))))) + (psOptions->bEnableDstAlpha +#ifdef HAVE_TIFF + || (EQUAL(psOptions->osFormat.c_str(), "COG") && + COGHasWarpingOptions(aosCreateOptions.List()) && + CPLTestBool( + aosCreateOptions.FetchNameValueDef("ADD_ALPHA", "YES"))) +#endif + )) { aosArgv.AddString("-addalpha"); } @@ -1309,6 +1300,7 @@ static GDALDatasetH GDALWarpIndirect(const char *pszDest, GDALDriverH hDriver, double dfStartPctCreateCopy = 0.0; if (hTmpDS == nullptr) { +#ifdef HAVE_TIFF // Special processing for COG output. As some of its options do // on-the-fly reprojection, take them into account now, and remove them // from the COG creation stage. @@ -1318,6 +1310,7 @@ static GDALDatasetH GDALWarpIndirect(const char *pszDest, GDALDriverH hDriver, { return nullptr; } +#endif // Materialize a temporary GeoTIFF with the result of the warp psOptions->osFormat = "GTiff"; @@ -2559,8 +2552,8 @@ static GDALDatasetH GDALWarpDirect(const char *pszDest, GDALDatasetH hDstDS, { CPLString osMsg; osMsg.Printf("Processing %s [%d/%d]", - GDALGetDescription(pahSrcDS[iSrc]), iSrc + 1, - nSrcCount); + CPLGetFilename(GDALGetDescription(pahSrcDS[iSrc])), + iSrc + 1, nSrcCount); return pfnExternalProgress((iSrc + dfComplete) / nSrcCount, osMsg.c_str(), pExternalProgressData); } @@ -2817,8 +2810,17 @@ static GDALDatasetH GDALWarpDirect(const char *pszDest, GDALDatasetH hDstDS, if (dfTargetRatio > 1.0) { - int iOvr = -1; - for (; iOvr < nOvCount - 1; iOvr++) + // Note: keep this logic for overview selection in sync between + // gdalwarp_lib.cpp and rasterio.cpp + const char *pszOversampligThreshold = CPLGetConfigOption( + "GDALWARP_OVERSAMPLING_THRESHOLD", nullptr); + const double dfOversamplingThreshold = + pszOversampligThreshold ? CPLAtof(pszOversampligThreshold) + : 1.0; + + int iBestOvr = -1; + double dfBestRatio = 0; + for (int iOvr = -1; iOvr < nOvCount; iOvr++) { const double dfOvrRatio = iOvr < 0 @@ -2827,18 +2829,27 @@ static GDALDatasetH GDALWarpDirect(const char *pszDest, GDALDatasetH hDstDS, poSrcDS->GetRasterBand(1) ->GetOverview(iOvr) ->GetXSize(); - const double dfNextOvrRatio = - static_cast(poSrcDS->GetRasterXSize()) / - poSrcDS->GetRasterBand(1) - ->GetOverview(iOvr + 1) - ->GetXSize(); - if (dfOvrRatio < dfTargetRatio && - dfNextOvrRatio > dfTargetRatio) - break; - if (fabs(dfOvrRatio - dfTargetRatio) < 1e-1) + + // Is it nearly the requested factor and better (lower) than + // the current best factor? + // Use an epsilon because of numerical instability. + constexpr double EPSILON = 1e-1; + if (dfOvrRatio >= + dfTargetRatio * dfOversamplingThreshold + EPSILON || + dfOvrRatio <= dfBestRatio) + { + continue; + } + + iBestOvr = iOvr; + dfBestRatio = dfOvrRatio; + if (std::abs(dfTargetRatio - dfOvrRatio) < EPSILON) + { break; + } } - iOvr += (psOptions->nOvLevel - OVR_LEVEL_AUTO); + const int iOvr = + iBestOvr + (psOptions->nOvLevel - OVR_LEVEL_AUTO); if (iOvr >= 0) { CPLDebug("WARP", "Selecting overview level %d for %s", iOvr, @@ -3416,7 +3427,7 @@ static CPLErr LoadCutline(const std::string &osCutlineDSNameOrWKT, OGRwkbGeometryType eType = wkbFlatten(poGeom->getGeometryType()); if (eType == wkbPolygon) - poMultiPolygon->addGeometryDirectly(poGeom.release()); + poMultiPolygon->addGeometry(std::move(poGeom)); else if (eType == wkbMultiPolygon) { for (const auto *poSubGeom : poGeom->toMultiPolygon()) @@ -4428,10 +4439,14 @@ static GDALDatasetH GDALWarpCreateOutput( nPixels = static_cast((psOptions->dfMaxX - psOptions->dfMinX + (psOptions->dfXRes / 2.0)) / psOptions->dfXRes); + if (nPixels == 0) + nPixels = 1; nLines = static_cast( (std::fabs(psOptions->dfMaxY - psOptions->dfMinY) + (psOptions->dfYRes / 2.0)) / psOptions->dfYRes); + if (nLines == 0) + nLines = 1; adfDstGeoTransform[0] = psOptions->dfMinX; adfDstGeoTransform[3] = psOptions->dfMaxY; adfDstGeoTransform[1] = psOptions->dfXRes; @@ -4445,7 +4460,7 @@ static GDALDatasetH GDALWarpCreateOutput( { // Try to detect if the edge of the raster would be blank // Cf https://github.com/OSGeo/gdal/issues/7905 - while (true) + while (nPixels > 1 || nLines > 1) { UpdateGeoTransformandAndPixelLines(); @@ -4547,18 +4562,30 @@ static GDALDatasetH GDALWarpCreateOutput( if (bTopBlankLine) { + if (psOptions->dfMaxY - psOptions->dfMinY <= + 2 * psOptions->dfYRes) + break; psOptions->dfMaxY -= psOptions->dfYRes; } if (bBottomBlankLine) { + if (psOptions->dfMaxY - psOptions->dfMinY <= + 2 * psOptions->dfYRes) + break; psOptions->dfMinY += psOptions->dfYRes; } if (bLeftBlankCol) { + if (psOptions->dfMaxX - psOptions->dfMinX <= + 2 * psOptions->dfXRes) + break; psOptions->dfMinX += psOptions->dfXRes; } if (bRightBlankCol) { + if (psOptions->dfMaxX - psOptions->dfMinX <= + 2 * psOptions->dfXRes) + break; psOptions->dfMaxX -= psOptions->dfXRes; } } @@ -4852,6 +4879,8 @@ static GDALDatasetH GDALWarpCreateOutput( class CutlineTransformer : public OGRCoordinateTransformation { + CPL_DISALLOW_COPY_ASSIGN(CutlineTransformer) + public: void *hSrcImageTransformer = nullptr; @@ -5372,7 +5401,7 @@ static CPLErr TransformCutlineToSource(GDALDataset *poSrcDS, { const double dfCutlineBlendDist = CPLAtof(CSLFetchNameValueDef( *ppapszWarpOptions, "CUTLINE_BLEND_DIST", "0")); - OGRLinearRing *poRing = new OGRLinearRing(); + auto poRing = std::make_unique(); poRing->addPoint(-dfCutlineBlendDist, -dfCutlineBlendDist); poRing->addPoint(-dfCutlineBlendDist, dfCutlineBlendDist + poSrcDS->GetRasterYSize()); @@ -5382,7 +5411,7 @@ static CPLErr TransformCutlineToSource(GDALDataset *poSrcDS, -dfCutlineBlendDist); poRing->addPoint(-dfCutlineBlendDist, -dfCutlineBlendDist); OGRPolygon oSrcDSFootprint; - oSrcDSFootprint.addRingDirectly(poRing); + oSrcDSFootprint.addRing(std::move(poRing)); OGREnvelope sSrcDSEnvelope; oSrcDSFootprint.getEnvelope(&sSrcDSEnvelope); OGREnvelope sCutlineEnvelope; @@ -5724,10 +5753,10 @@ GDALWarpAppOptionsGetParser(GDALWarpAppOptions *psOptions, argParser->add_argument("-et") .metavar("") + .store_into(psOptions->dfErrorThreshold) .action( - [psOptions](const std::string &s) + [psOptions](const std::string &) { - psOptions->dfErrorThreshold = CPLAtofM(s.c_str()); psOptions->aosWarpOptions.AddString(CPLSPrintf( "ERROR_THRESHOLD=%.16g", psOptions->dfErrorThreshold)); }) @@ -5738,11 +5767,21 @@ GDALWarpAppOptionsGetParser(GDALWarpAppOptions *psOptions, .action( [psOptions](const std::string &s) { - if (CPLAtofM(s.c_str()) < 10000) - psOptions->dfWarpMemoryLimit = - CPLAtofM(s.c_str()) * 1024 * 1024; + bool bUnitSpecified = false; + GIntBig nBytes; + if (CPLParseMemorySize(s.c_str(), &nBytes, &bUnitSpecified) == + CE_None) + { + if (!bUnitSpecified && nBytes < 10000) + { + nBytes *= (1024 * 1024); + } + psOptions->dfWarpMemoryLimit = static_cast(nBytes); + } else - psOptions->dfWarpMemoryLimit = CPLAtofM(s.c_str()); + { + throw std::invalid_argument("Failed to parse value of -wm"); + } }) .help(_("Set max warp memory.")); diff --git a/apps/gdalwarpsimple.c b/apps/gdalwarpsimple.c deleted file mode 100644 index 136caec00009..000000000000 --- a/apps/gdalwarpsimple.c +++ /dev/null @@ -1,467 +0,0 @@ -/****************************************************************************** - * - * Project: Mapinfo Image Warper - * Purpose: Commandline program for doing a variety of image warps, including - * image reprojection. - * Author: Frank Warmerdam - * - ****************************************************************************** - * Copyright (c) 2002, i3 - information integration and imaging - * Fort Collin, CO - * - * 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. - ****************************************************************************/ - -#include "gdal_alg.h" -#include "cpl_string.h" -#include "ogr_srs_api.h" - -static GDALDatasetH GDALWarpCreateOutput(GDALDatasetH hSrcDS, - const char *pszFilename, - const char *pszFormat, - const char *pszSourceSRS, - const char *pszTargetSRS, int nOrder, - char **papszCreateOptions); - -static double dfMinX = 0.0, dfMinY = 0.0, dfMaxX = 0.0, dfMaxY = 0.0; -static double dfXRes = 0.0, dfYRes = 0.0; -static int nForcePixels = 0, nForceLines = 0; - -/************************************************************************/ -/* Usage() */ -/************************************************************************/ - -static void Usage() - -{ - printf("Usage: gdalwarpsimple [--version] [--formats]\n" - " [-s_srs ] [-t_srs ] [-order ] [-et " - "]\n" - " [-te ] [-tr ] [-ts " - " ]\n" - " [-of ] [-co =]... \n"); - exit(1); -} - -/************************************************************************/ -/* SanitizeSRS */ -/************************************************************************/ - -char *SanitizeSRS(const char *pszUserInput) - -{ - OGRSpatialReferenceH hSRS; - char *pszResult = NULL; - - CPLErrorReset(); - - hSRS = OSRNewSpatialReference(NULL); - if (OSRSetFromUserInput(hSRS, pszUserInput) == OGRERR_NONE) - OSRExportToWkt(hSRS, &pszResult); - else - { - CPLError(CE_Failure, CPLE_AppDefined, - "Translating source or target SRS failed:\n%s", pszUserInput); - exit(1); - } - - OSRDestroySpatialReference(hSRS); - - return pszResult; -} - -/************************************************************************/ -/* main() */ -/************************************************************************/ - -int main(int argc, char **argv) - -{ - GDALDatasetH hSrcDS, hDstDS; - const char *pszFormat = "GTiff"; - char *pszTargetSRS = NULL; - char *pszSourceSRS = NULL; - const char *pszSrcFilename = NULL, *pszDstFilename = NULL; - int bCreateOutput = FALSE, i, nOrder = 0; - void *hTransformArg, *hGenImgProjArg = NULL, *hApproxArg = NULL; - char **papszWarpOptions = NULL; - double dfErrorThreshold = 0.125; - GDALTransformerFunc pfnTransformer = NULL; - char **papszCreateOptions = NULL; - - GDALAllRegister(); - - /* -------------------------------------------------------------------- */ - /* Parse arguments. */ - /* -------------------------------------------------------------------- */ - for (i = 1; i < argc; i++) - { - if (EQUAL(argv[i], "--version")) - { - printf("%s\n", GDALVersionInfo("--version")); - exit(0); - } - else if (EQUAL(argv[i], "--formats")) - { - int iDr; - - printf("Supported Formats:\n"); - for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) - { - GDALDriverH hDriver = GDALGetDriver(iDr); - - printf(" %s: %s\n", GDALGetDriverShortName(hDriver), - GDALGetDriverLongName(hDriver)); - } - - exit(0); - } - else if (EQUAL(argv[i], "-co") && i < argc - 1) - { - papszCreateOptions = CSLAddString(papszCreateOptions, argv[++i]); - bCreateOutput = TRUE; - } - else if (EQUAL(argv[i], "-of") && i < argc - 1) - { - pszFormat = argv[++i]; - bCreateOutput = TRUE; - } - else if (EQUAL(argv[i], "-t_srs") && i < argc - 1) - { - pszTargetSRS = SanitizeSRS(argv[++i]); - } - else if (EQUAL(argv[i], "-s_srs") && i < argc - 1) - { - pszSourceSRS = SanitizeSRS(argv[++i]); - } - else if (EQUAL(argv[i], "-order") && i < argc - 1) - { - nOrder = atoi(argv[++i]); - } - else if (EQUAL(argv[i], "-et") && i < argc - 1) - { - dfErrorThreshold = CPLAtof(argv[++i]); - } - else if (EQUAL(argv[i], "-tr") && i < argc - 2) - { - dfXRes = CPLAtof(argv[++i]); - dfYRes = fabs(CPLAtof(argv[++i])); - bCreateOutput = TRUE; - } - else if (EQUAL(argv[i], "-ts") && i < argc - 2) - { - nForcePixels = atoi(argv[++i]); - nForceLines = atoi(argv[++i]); - bCreateOutput = TRUE; - } - else if (EQUAL(argv[i], "-te") && i < argc - 4) - { - dfMinX = CPLAtof(argv[++i]); - dfMinY = CPLAtof(argv[++i]); - dfMaxX = CPLAtof(argv[++i]); - dfMaxY = CPLAtof(argv[++i]); - bCreateOutput = TRUE; - } - else if (argv[i][0] == '-') - Usage(); - else if (pszSrcFilename == NULL) - pszSrcFilename = argv[i]; - else if (pszDstFilename == NULL) - pszDstFilename = argv[i]; - else - Usage(); - } - - if (pszDstFilename == NULL) - Usage(); - - /* -------------------------------------------------------------------- */ - /* Open source dataset. */ - /* -------------------------------------------------------------------- */ - hSrcDS = GDALOpen(pszSrcFilename, GA_ReadOnly); - - if (hSrcDS == NULL) - exit(2); - - /* -------------------------------------------------------------------- */ - /* Check that there's at least one raster band */ - /* -------------------------------------------------------------------- */ - if (GDALGetRasterCount(hSrcDS) == 0) - { - fprintf(stderr, "Input file %s has no raster bands.\n", pszSrcFilename); - exit(2); - } - - if (pszSourceSRS == NULL) - { - if (GDALGetProjectionRef(hSrcDS) != NULL && - strlen(GDALGetProjectionRef(hSrcDS)) > 0) - pszSourceSRS = CPLStrdup(GDALGetProjectionRef(hSrcDS)); - - else if (GDALGetGCPProjection(hSrcDS) != NULL && - strlen(GDALGetGCPProjection(hSrcDS)) > 0 && - GDALGetGCPCount(hSrcDS) > 1) - pszSourceSRS = CPLStrdup(GDALGetGCPProjection(hSrcDS)); - else - pszSourceSRS = CPLStrdup(""); - } - - if (pszTargetSRS == NULL) - pszTargetSRS = CPLStrdup(pszSourceSRS); - - /* -------------------------------------------------------------------- */ - /* Does the output dataset already exist? */ - /* -------------------------------------------------------------------- */ - CPLPushErrorHandler(CPLQuietErrorHandler); - hDstDS = GDALOpen(pszDstFilename, GA_Update); - CPLPopErrorHandler(); - - if (hDstDS != NULL && bCreateOutput) - { - fprintf( - stderr, - "Output dataset %s exists,\n" - "but some commandline options were provided indicating a new " - "dataset\n" - "should be created. Please delete existing dataset and run again.", - pszDstFilename); - exit(1); - } - - /* -------------------------------------------------------------------- */ - /* If not, we need to create it. */ - /* -------------------------------------------------------------------- */ - if (hDstDS == NULL) - { - hDstDS = GDALWarpCreateOutput(hSrcDS, pszDstFilename, pszFormat, - pszSourceSRS, pszTargetSRS, nOrder, - papszCreateOptions); - papszWarpOptions = CSLSetNameValue(papszWarpOptions, "INIT", "0"); - CSLDestroy(papszCreateOptions); - papszCreateOptions = NULL; - } - - if (hDstDS == NULL) - exit(1); - - /* -------------------------------------------------------------------- */ - /* Create a transformation object from the source to */ - /* destination coordinate system. */ - /* -------------------------------------------------------------------- */ - hTransformArg = hGenImgProjArg = GDALCreateGenImgProjTransformer( - hSrcDS, pszSourceSRS, hDstDS, pszTargetSRS, TRUE, 1000.0, nOrder); - - if (hTransformArg == NULL) - exit(1); - - pfnTransformer = GDALGenImgProjTransform; - - /* -------------------------------------------------------------------- */ - /* Warp the transformer with a linear approximator unless the */ - /* acceptable error is zero. */ - /* -------------------------------------------------------------------- */ - if (dfErrorThreshold != 0.0) - { - hTransformArg = hApproxArg = GDALCreateApproxTransformer( - GDALGenImgProjTransform, hGenImgProjArg, dfErrorThreshold); - pfnTransformer = GDALApproxTransform; - } - - /* -------------------------------------------------------------------- */ - /* Now actually invoke the warper to do the work. */ - /* -------------------------------------------------------------------- */ - GDALSimpleImageWarp(hSrcDS, hDstDS, 0, NULL, pfnTransformer, hTransformArg, - GDALTermProgress, NULL, papszWarpOptions); - - CSLDestroy(papszWarpOptions); - - if (hApproxArg != NULL) - GDALDestroyApproxTransformer(hApproxArg); - - if (hGenImgProjArg != NULL) - GDALDestroyGenImgProjTransformer(hGenImgProjArg); - - /* -------------------------------------------------------------------- */ - /* Cleanup. */ - /* -------------------------------------------------------------------- */ - GDALClose(hDstDS); - GDALClose(hSrcDS); - - GDALDumpOpenDatasets(stderr); - - GDALDestroyDriverManager(); - - exit(0); -} - -/************************************************************************/ -/* GDALWarpCreateOutput() */ -/* */ -/* Create the output file based on various commandline options, */ -/* and the input file. */ -/************************************************************************/ - -static GDALDatasetH GDALWarpCreateOutput(GDALDatasetH hSrcDS, - const char *pszFilename, - const char *pszFormat, - const char *pszSourceSRS, - const char *pszTargetSRS, int nOrder, - char **papszCreateOptions) - -{ - GDALDriverH hDriver; - GDALDatasetH hDstDS; - void *hTransformArg; - double adfDstGeoTransform[6]; - int nPixels = 0, nLines = 0; - GDALColorTableH hCT; - - /* -------------------------------------------------------------------- */ - /* Find the output driver. */ - /* -------------------------------------------------------------------- */ - hDriver = GDALGetDriverByName(pszFormat); - if (hDriver == NULL || - GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) == NULL) - { - int iDr; - - printf("Output driver `%s' not recognised or does not support\n", - pszFormat); - printf("direct output file creation. The following format drivers are " - "configured\n" - "and support direct output:\n"); - - for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) - { - GDALDriverH hDriver = GDALGetDriver(iDr); - - if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) != NULL) - { - printf(" %s: %s\n", GDALGetDriverShortName(hDriver), - GDALGetDriverLongName(hDriver)); - } - } - printf("\n"); - exit(1); - } - - /* -------------------------------------------------------------------- */ - /* Create a transformation object from the source to */ - /* destination coordinate system. */ - /* -------------------------------------------------------------------- */ - hTransformArg = GDALCreateGenImgProjTransformer( - hSrcDS, pszSourceSRS, NULL, pszTargetSRS, TRUE, 1000.0, nOrder); - - if (hTransformArg == NULL) - return NULL; - - /* -------------------------------------------------------------------- */ - /* Get approximate output definition. */ - /* -------------------------------------------------------------------- */ - if (GDALSuggestedWarpOutput(hSrcDS, GDALGenImgProjTransform, hTransformArg, - adfDstGeoTransform, &nPixels, - &nLines) != CE_None) - return NULL; - - GDALDestroyGenImgProjTransformer(hTransformArg); - - /* -------------------------------------------------------------------- */ - /* Did the user override some parameters? */ - /* -------------------------------------------------------------------- */ - if (dfXRes != 0.0 && dfYRes != 0.0) - { - CPLAssert(nPixels == 0 && nLines == 0); - if (dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0) - { - dfMinX = adfDstGeoTransform[0]; - dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels; - dfMaxY = adfDstGeoTransform[3]; - dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines; - } - - nPixels = (int)((dfMaxX - dfMinX + (dfXRes / 2.0)) / dfXRes); - nLines = (int)((dfMaxY - dfMinY + (dfYRes / 2.0)) / dfYRes); - adfDstGeoTransform[0] = dfMinX; - adfDstGeoTransform[3] = dfMaxY; - adfDstGeoTransform[1] = dfXRes; - adfDstGeoTransform[5] = -dfYRes; - } - - else if (nForcePixels != 0 && nForceLines != 0) - { - if (dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0) - { - dfMinX = adfDstGeoTransform[0]; - dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels; - dfMaxY = adfDstGeoTransform[3]; - dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines; - } - - dfXRes = (dfMaxX - dfMinX) / nForcePixels; - dfYRes = (dfMaxY - dfMinY) / nForceLines; - - adfDstGeoTransform[0] = dfMinX; - adfDstGeoTransform[3] = dfMaxY; - adfDstGeoTransform[1] = dfXRes; - adfDstGeoTransform[5] = -dfYRes; - - nPixels = nForcePixels; - nLines = nForceLines; - } - - else if (dfMinX != 0.0 || dfMinY != 0.0 || dfMaxX != 0.0 || dfMaxY != 0.0) - { - dfXRes = adfDstGeoTransform[1]; - dfYRes = fabs(adfDstGeoTransform[5]); - - nPixels = (int)((dfMaxX - dfMinX + (dfXRes / 2.0)) / dfXRes); - nLines = (int)((dfMaxY - dfMinY + (dfYRes / 2.0)) / dfYRes); - - adfDstGeoTransform[0] = dfMinX; - adfDstGeoTransform[3] = dfMaxY; - } - - /* -------------------------------------------------------------------- */ - /* Create the output file. */ - /* -------------------------------------------------------------------- */ - printf("Creating output file is that %dP x %dL.\n", nPixels, nLines); - - hDstDS = GDALCreate(hDriver, pszFilename, nPixels, nLines, - GDALGetRasterCount(hSrcDS), - GDALGetRasterDataType(GDALGetRasterBand(hSrcDS, 1)), - papszCreateOptions); - - if (hDstDS == NULL) - return NULL; - - /* -------------------------------------------------------------------- */ - /* Write out the projection definition. */ - /* -------------------------------------------------------------------- */ - GDALSetProjection(hDstDS, pszTargetSRS); - GDALSetGeoTransform(hDstDS, adfDstGeoTransform); - - /* -------------------------------------------------------------------- */ - /* Copy the color table, if required. */ - /* -------------------------------------------------------------------- */ - hCT = GDALGetRasterColorTable(GDALGetRasterBand(hSrcDS, 1)); - if (hCT != NULL) - GDALSetRasterColorTable(GDALGetRasterBand(hDstDS, 1), hCT); - - return hDstDS; -} diff --git a/apps/gnmanalyse.cpp b/apps/gnmanalyse.cpp index 029294ee8bc1..a318dde69e21 100644 --- a/apps/gnmanalyse.cpp +++ b/apps/gnmanalyse.cpp @@ -8,23 +8,7 @@ * Copyright (C) 2014 Mikhail Gusev * Copyright (c) 2014-2015, NextGIS * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "commonutils.h" diff --git a/apps/gnmmanage.cpp b/apps/gnmmanage.cpp index 77f6dcdccde2..ef21df7f9c01 100644 --- a/apps/gnmmanage.cpp +++ b/apps/gnmmanage.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2014, Mikhail Gusev * Copyright (c) 2014-2015, NextGIS * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "commonutils.h" diff --git a/apps/multireadtest.cpp b/apps/multireadtest.cpp index d8a4e1cc24b8..522e533a3a3b 100644 --- a/apps/multireadtest.cpp +++ b/apps/multireadtest.cpp @@ -7,50 +7,39 @@ ****************************************************************************** * Copyright (c) 2005, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" #include "gdal_alg.h" #include "cpl_multiproc.h" #include "cpl_string.h" + +#include +#include +#include #include static int nIterations = 1; static bool bLockOnOpen = false; static int nOpenIterations = 1; static volatile int nPendingThreads = 0; +static bool bThreadCanFinish = false; +static std::mutex oMutex; +static std::condition_variable oCond; static const char *pszFilename = nullptr; static int nChecksum = 0; static int nWidth = 0; static int nHeight = 0; -static CPLMutex *pGlobalMutex = nullptr; - /************************************************************************/ /* Usage() */ /************************************************************************/ static void Usage() { - printf("multireadtest [-lock_on_open] [-open_in_main] [-t ]\n" - " [-i ] [-oi ]\n" + printf("multireadtest [[-thread_safe] | [[-lock_on_open] [-open_in_main]]\n" + " [-t ] [-i ] [-oi ]\n" " [-width ] [-height ]\n" " filename\n"); exit(1); @@ -74,12 +63,12 @@ static void WorkerFunc(void *arg) else { if (bLockOnOpen) - CPLAcquireMutex(pGlobalMutex, 100.0); + oMutex.lock(); hDS = GDALOpen(pszFilename, GA_ReadOnly); if (bLockOnOpen) - CPLReleaseMutex(pGlobalMutex); + oMutex.unlock(); } for (int iIter = 0; iIter < nIterations && hDS != nullptr; iIter++) @@ -99,10 +88,10 @@ static void WorkerFunc(void *arg) if (hDS && hDSIn == nullptr) { if (bLockOnOpen) - CPLAcquireMutex(pGlobalMutex, 100.0); + oMutex.lock(); GDALClose(hDS); if (bLockOnOpen) - CPLReleaseMutex(pGlobalMutex); + oMutex.unlock(); } else if (hDSIn != nullptr) { @@ -110,9 +99,13 @@ static void WorkerFunc(void *arg) } } - CPLAcquireMutex(pGlobalMutex, 100.0); - nPendingThreads--; - CPLReleaseMutex(pGlobalMutex); + { + std::unique_lock oLock(oMutex); + nPendingThreads--; + oCond.notify_all(); + while (!bThreadCanFinish) + oCond.wait(oLock); + } } /************************************************************************/ @@ -131,6 +124,10 @@ int main(int argc, char **argv) int nThreadCount = 4; bool bOpenInThreads = true; + bool bThreadSafe = false; + bool bJoinAfterClosing = false; + bool bDetach = false; + bool bClose = true; for (int iArg = 1; iArg < argc; iArg++) { @@ -154,6 +151,10 @@ int main(int argc, char **argv) { nHeight = atoi(argv[++iArg]); } + else if (EQUAL(argv[iArg], "-thread_safe")) + { + bThreadSafe = true; + } else if (EQUAL(argv[iArg], "-lock_on_open")) { bLockOnOpen = true; @@ -162,6 +163,18 @@ int main(int argc, char **argv) { bOpenInThreads = false; } + else if (EQUAL(argv[iArg], "-join_after_closing")) + { + bJoinAfterClosing = true; + } + else if (EQUAL(argv[iArg], "-detach")) + { + bDetach = true; + } + else if (EQUAL(argv[iArg], "-do_not_close")) + { + bClose = false; + } else if (pszFilename == nullptr) { pszFilename = argv[iArg]; @@ -186,12 +199,10 @@ int main(int argc, char **argv) /* -------------------------------------------------------------------- */ /* Get the checksum of band1. */ /* -------------------------------------------------------------------- */ - GDALDatasetH hDS = nullptr; - GDALAllRegister(); for (int i = 0; i < 2; i++) { - hDS = GDALOpen(pszFilename, GA_ReadOnly); + GDALDatasetH hDS = GDALOpen(pszFilename, GA_ReadOnly); if (hDS == nullptr) exit(1); @@ -210,39 +221,83 @@ int main(int argc, char **argv) /* -------------------------------------------------------------------- */ /* Fire off worker threads. */ /* -------------------------------------------------------------------- */ - pGlobalMutex = CPLCreateMutex(); - CPLReleaseMutex(pGlobalMutex); nPendingThreads = nThreadCount; + GDALDatasetH hThreadSafeDS = nullptr; + if (bThreadSafe) + { + hThreadSafeDS = + GDALOpenEx(pszFilename, GDAL_OF_RASTER | GDAL_OF_THREAD_SAFE, + nullptr, nullptr, nullptr); + if (!hThreadSafeDS) + exit(1); + } + std::vector aoThreads; std::vector aoDS; for (int iThread = 0; iThread < nThreadCount; iThread++) { - hDS = nullptr; - if (!bOpenInThreads) + GDALDatasetH hDS = nullptr; + if (bThreadSafe) { - hDS = GDALOpen(pszFilename, GA_ReadOnly); - if (!hDS) + hDS = hThreadSafeDS; + } + else + { + if (!bOpenInThreads) { - printf("GDALOpen() failed.\n"); - exit(1); + hDS = GDALOpen(pszFilename, GA_ReadOnly); + if (!hDS) + { + printf("GDALOpen() failed.\n"); + exit(1); + } + aoDS.push_back(hDS); } - aoDS.push_back(hDS); } - if (CPLCreateThread(WorkerFunc, hDS) == -1) + aoThreads.push_back(std::thread([hDS]() { WorkerFunc(hDS); })); + } + + { + std::unique_lock oLock(oMutex); + while (nPendingThreads > 0) { - printf("CPLCreateThread() failed.\n"); - exit(1); + // printf("nPendingThreads = %d\n", nPendingThreads); + oCond.wait(oLock); } } - while (nPendingThreads > 0) - CPLSleep(0.5); - - CPLDestroyMutex(pGlobalMutex); + if (!bJoinAfterClosing && !bDetach) + { + { + std::lock_guard oLock(oMutex); + bThreadCanFinish = true; + oCond.notify_all(); + } + for (auto &oThread : aoThreads) + oThread.join(); + } for (size_t i = 0; i < aoDS.size(); ++i) GDALClose(aoDS[i]); + if (bClose) + GDALClose(hThreadSafeDS); + + if (bDetach) + { + for (auto &oThread : aoThreads) + oThread.detach(); + } + else if (bJoinAfterClosing) + { + { + std::lock_guard oLock(oMutex); + bThreadCanFinish = true; + oCond.notify_all(); + } + for (auto &oThread : aoThreads) + oThread.join(); + } printf("All threads complete.\n"); @@ -250,5 +305,13 @@ int main(int argc, char **argv) GDALDestroyDriverManager(); + { + std::lock_guard oLock(oMutex); + bThreadCanFinish = true; + oCond.notify_all(); + } + + printf("End of main.\n"); + return 0; } diff --git a/apps/nearblack_bin.cpp b/apps/nearblack_bin.cpp index 244bc00743f4..cd870959b628 100644 --- a/apps/nearblack_bin.cpp +++ b/apps/nearblack_bin.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/nearblack_lib.cpp b/apps/nearblack_lib.cpp index ff801ace9a99..44ea36923bda 100644 --- a/apps/nearblack_lib.cpp +++ b/apps/nearblack_lib.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2006, MapShots Inc (www.mapshots.com) * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/nearblack_lib.h b/apps/nearblack_lib.h index e90b12cd768a..68f85f4ac001 100644 --- a/apps/nearblack_lib.h +++ b/apps/nearblack_lib.h @@ -8,23 +8,7 @@ * Copyright (c) 2006, MapShots Inc (www.mapshots.com) * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef NEARBLACK_LIB_H diff --git a/apps/nearblack_lib_floodfill.cpp b/apps/nearblack_lib_floodfill.cpp index da29fb236f32..541a3ddd7b4e 100644 --- a/apps/nearblack_lib_floodfill.cpp +++ b/apps/nearblack_lib_floodfill.cpp @@ -8,23 +8,7 @@ * **************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_priv.h" diff --git a/apps/ogr2ogr_bin.cpp b/apps/ogr2ogr_bin.cpp index 1fa30d46b5ff..92a8647a2267 100644 --- a/apps/ogr2ogr_bin.cpp +++ b/apps/ogr2ogr_bin.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2008-2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -47,7 +31,6 @@ #include "gdal_priv.h" #include "gdal_utils.h" #include "gdal_utils_priv.h" -#include "gdal_version.h" #include "ogr_api.h" #include "ogr_core.h" #include "ogr_p.h" diff --git a/apps/ogr2ogr_lib.cpp b/apps/ogr2ogr_lib.cpp index 16b3539ddd42..19734944335d 100644 --- a/apps/ogr2ogr_lib.cpp +++ b/apps/ogr2ogr_lib.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2008-2015, Even Rouault * Copyright (c) 2015, Faza Mahamood * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" @@ -40,9 +24,12 @@ #include #include +#include +#include #include #include #include +#include #include #include #include @@ -68,8 +55,10 @@ #include "ogr_p.h" #include "ogr_recordbatch.h" #include "ogr_spatialref.h" +#include "ogrlayerarrow.h" #include "ogrlayerdecorator.h" #include "ogrsf_frmts.h" +#include "ogr_wkb.h" typedef enum { @@ -128,6 +117,8 @@ struct CopyableGCPs CPLFree(pasGCPs); } } + + CopyableGCPs &operator=(const CopyableGCPs &) = delete; }; } // namespace gdal::ogr2ogr_lib @@ -428,7 +419,7 @@ struct GDALVectorTranslateOptions whose geometry intersects the extents will be selected. The geometries will not be clipped unless GDALVectorTranslateOptions::bClipSrc is true. */ - std::shared_ptr poSpatialFilter; + std::shared_ptr poSpatialFilter{}; /*! the progress function to use */ GDALProgressFunc pfnProgress = nullptr; @@ -503,6 +494,7 @@ struct TargetLayerInfo const char *m_pszGeomField = nullptr; std::vector m_anDateTimeFieldIdx{}; bool m_bSupportCurves = false; + OGRArrowArrayStream m_sArrowArrayStream{}; }; struct AssociatedLayers @@ -516,41 +508,43 @@ class SetupTargetLayer bool CanUseWriteArrowBatch(OGRLayer *poSrcLayer, OGRLayer *poDstLayer, bool bJustCreatedLayer, const GDALVectorTranslateOptions *psOptions, - bool &bError); + bool bPreserveFID, bool &bError, + OGRArrowArrayStream &streamSrc); public: - GDALDataset *m_poSrcDS; - GDALDataset *m_poDstDS; - char **m_papszLCO; - OGRSpatialReference *m_poOutputSRS; + GDALDataset *m_poSrcDS = nullptr; + GDALDataset *m_poDstDS = nullptr; + CSLConstList m_papszLCO = nullptr; + const OGRSpatialReference *m_poUserSourceSRS = nullptr; + const OGRSpatialReference *m_poOutputSRS = nullptr; bool m_bTransform = false; - bool m_bNullifyOutputSRS; + bool m_bNullifyOutputSRS = false; bool m_bSelFieldsSet = false; - char **m_papszSelFields; - bool m_bAppend; - bool m_bAddMissingFields; - int m_eGType; - GeomTypeConversion m_eGeomTypeConversion; - int m_nCoordDim; - bool m_bOverwrite; - char **m_papszFieldTypesToString; - char **m_papszMapFieldType; - bool m_bUnsetFieldWidth; - bool m_bExplodeCollections; - const char *m_pszZField; - char **m_papszFieldMap; - const char *m_pszWHERE; - bool m_bExactFieldNameMatch; - bool m_bQuiet; - bool m_bForceNullable; - bool m_bResolveDomains; - bool m_bUnsetDefault; - bool m_bUnsetFid; - bool m_bPreserveFID; - bool m_bCopyMD; - bool m_bNativeData; - bool m_bNewDataSource; - const char *m_pszCTPipeline; + CSLConstList m_papszSelFields = nullptr; + bool m_bAppend = false; + bool m_bAddMissingFields = false; + int m_eGType = 0; + GeomTypeConversion m_eGeomTypeConversion = GTC_DEFAULT; + int m_nCoordDim = 0; + bool m_bOverwrite = false; + CSLConstList m_papszFieldTypesToString = nullptr; + CSLConstList m_papszMapFieldType = nullptr; + bool m_bUnsetFieldWidth = false; + bool m_bExplodeCollections = false; + const char *m_pszZField = nullptr; + CSLConstList m_papszFieldMap = nullptr; + const char *m_pszWHERE = nullptr; + bool m_bExactFieldNameMatch = false; + bool m_bQuiet = false; + bool m_bForceNullable = false; + bool m_bResolveDomains = false; + bool m_bUnsetDefault = false; + bool m_bUnsetFid = false; + bool m_bPreserveFID = false; + bool m_bCopyMD = false; + bool m_bNativeData = false; + bool m_bNewDataSource = false; + const char *m_pszCTPipeline = nullptr; std::unique_ptr Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, @@ -559,11 +553,10 @@ class SetupTargetLayer class LayerTranslator { - static bool TranslateArrow(const TargetLayerInfo *psInfo, - GIntBig nCountLayerFeatures, - GIntBig *pnReadFeatureCount, - GDALProgressFunc pfnProgress, void *pProgressArg, - const GDALVectorTranslateOptions *psOptions); + bool TranslateArrow(TargetLayerInfo *psInfo, GIntBig nCountLayerFeatures, + GIntBig *pnReadFeatureCount, + GDALProgressFunc pfnProgress, void *pProgressArg, + const GDALVectorTranslateOptions *psOptions); public: GDALDataset *m_poSrcDS = nullptr; @@ -571,9 +564,9 @@ class LayerTranslator bool m_bTransform = false; bool m_bWrapDateline = false; CPLString m_osDateLineOffset{}; - OGRSpatialReference *m_poOutputSRS = nullptr; + const OGRSpatialReference *m_poOutputSRS = nullptr; bool m_bNullifyOutputSRS = false; - OGRSpatialReference *m_poUserSourceSRS = nullptr; + const OGRSpatialReference *m_poUserSourceSRS = nullptr; OGRCoordinateTransformation *m_poGCPCoordTrans = nullptr; int m_eGType = -1; GeomTypeConversion m_eGeomTypeConversion = GTC_DEFAULT; @@ -585,20 +578,20 @@ class LayerTranslator OGRGeometry *m_poClipSrcOri = nullptr; bool m_bWarnedClipSrcSRS = false; - std::unique_ptr m_poClipSrcReprojectedToSrcSRS; + std::unique_ptr m_poClipSrcReprojectedToSrcSRS{}; const OGRSpatialReference *m_poClipSrcReprojectedToSrcSRS_SRS = nullptr; OGREnvelope m_oClipSrcEnv{}; OGRGeometry *m_poClipDstOri = nullptr; bool m_bWarnedClipDstSRS = false; - std::unique_ptr m_poClipDstReprojectedToDstSRS; + std::unique_ptr m_poClipDstReprojectedToDstSRS{}; const OGRSpatialReference *m_poClipDstReprojectedToDstSRS_SRS = nullptr; OGREnvelope m_oClipDstEnv{}; bool m_bExplodeCollections = false; bool m_bNativeData = false; GIntBig m_nLimit = -1; - OGRGeometryFactory::TransformWithOptionsCache m_transformWithOptionsCache; + OGRGeometryFactory::TransformWithOptionsCache m_transformWithOptionsCache{}; bool Translate(OGRFeature *poFeatureIn, TargetLayerInfo *psInfo, GIntBig nCountLayerFeatures, GIntBig *pnReadFeatureCount, @@ -695,13 +688,13 @@ static std::unique_ptr LoadGeometry(const std::string &osDS, "should be manually inspected.", poFeat->GetFID(), osDS.c_str()); - oGC.addGeometryDirectly(poValid.release()); + oGC.addGeometry(std::move(poValid)); } else { CPLError(CE_Failure, CPLE_AppDefined, "Geometry of feature " CPL_FRMT_GIB " of %s " - "is invalid, and could not been made valid.", + "is invalid, and could not be made valid.", poFeat->GetFID(), osDS.c_str()); oGC.empty(); break; @@ -709,7 +702,7 @@ static std::unique_ptr LoadGeometry(const std::string &osDS, } else { - oGC.addGeometryDirectly(poSrcGeom.release()); + oGC.addGeometry(std::move(poSrcGeom)); } } } @@ -738,15 +731,17 @@ typedef struct class OGRSplitListFieldLayer : public OGRLayer { - OGRLayer *poSrcLayer; - OGRFeatureDefn *poFeatureDefn; - ListFieldDesc *pasListFields; - int nListFieldCount; - int nMaxSplitListSubFields; + OGRLayer *poSrcLayer = nullptr; + OGRFeatureDefn *poFeatureDefn = nullptr; + ListFieldDesc *pasListFields = nullptr; + int nListFieldCount = 0; + const int nMaxSplitListSubFields; std::unique_ptr TranslateFeature(std::unique_ptr poSrcFeature); + CPL_DISALLOW_COPY_ASSIGN(OGRSplitListFieldLayer) + public: OGRSplitListFieldLayer(OGRLayer *poSrcLayer, int nMaxSplitListSubFields); virtual ~OGRSplitListFieldLayer(); @@ -821,8 +816,7 @@ class OGRSplitListFieldLayer : public OGRLayer OGRSplitListFieldLayer::OGRSplitListFieldLayer(OGRLayer *poSrcLayerIn, int nMaxSplitListSubFieldsIn) - : poSrcLayer(poSrcLayerIn), poFeatureDefn(nullptr), pasListFields(nullptr), - nListFieldCount(0), + : poSrcLayer(poSrcLayerIn), nMaxSplitListSubFields( nMaxSplitListSubFieldsIn < 0 ? INT_MAX : nMaxSplitListSubFieldsIn) { @@ -1205,6 +1199,14 @@ class GCPCoordTransformation : public OGRCoordinateTransformation virtual OGRCoordinateTransformation *GetInverse() const override { + static std::once_flag flag; + std::call_once(flag, + []() + { + CPLDebug("OGR2OGR", + "GCPCoordTransformation::GetInverse() " + "called, but not implemented"); + }); return nullptr; } }; @@ -1215,20 +1217,24 @@ class GCPCoordTransformation : public OGRCoordinateTransformation class CompositeCT : public OGRCoordinateTransformation { + OGRCoordinateTransformation *const poCT1; + const bool bOwnCT1; + OGRCoordinateTransformation *const poCT2; + const bool bOwnCT2; + + // Working buffer + std::vector m_anErrorCode{}; + CompositeCT(const CompositeCT &other) : poCT1(other.poCT1 ? other.poCT1->Clone() : nullptr), bOwnCT1(true), - poCT2(other.poCT2 ? other.poCT2->Clone() : nullptr), bOwnCT2(true) + poCT2(other.poCT2 ? other.poCT2->Clone() : nullptr), bOwnCT2(true), + m_anErrorCode({}) { } CompositeCT &operator=(const CompositeCT &) = delete; public: - OGRCoordinateTransformation *poCT1; - bool bOwnCT1; - OGRCoordinateTransformation *poCT2; - bool bOwnCT2; - CompositeCT(OGRCoordinateTransformation *poCT1In, bool bOwnCT1In, OGRCoordinateTransformation *poCT2In, bool bOwnCT2In) : poCT1(poCT1In), bOwnCT1(bOwnCT1In), poCT2(poCT2In), bOwnCT2(bOwnCT2In) @@ -1290,9 +1296,52 @@ class CompositeCT : public OGRCoordinateTransformation return nResult; } + virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y, + double *z, double *t, + int *panErrorCodes) override + { + if (poCT1 && poCT2 && panErrorCodes) + { + m_anErrorCode.resize(nCount); + int nResult = poCT1->TransformWithErrorCodes(nCount, x, y, z, t, + m_anErrorCode.data()); + if (nResult) + nResult = poCT2->TransformWithErrorCodes(nCount, x, y, z, t, + panErrorCodes); + for (size_t i = 0; i < nCount; ++i) + { + if (m_anErrorCode[i]) + panErrorCodes[i] = m_anErrorCode[i]; + } + return nResult; + } + int nResult = TRUE; + if (poCT1) + nResult = poCT1->TransformWithErrorCodes(nCount, x, y, z, t, + panErrorCodes); + if (nResult && poCT2) + nResult = poCT2->TransformWithErrorCodes(nCount, x, y, z, t, + panErrorCodes); + return nResult; + } + virtual OGRCoordinateTransformation *GetInverse() const override { - return nullptr; + if (!poCT1 && !poCT2) + return nullptr; + if (!poCT2) + return poCT1->GetInverse(); + if (!poCT1) + return poCT2->GetInverse(); + auto poInvCT1 = + std::unique_ptr(poCT1->GetInverse()); + auto poInvCT2 = + std::unique_ptr(poCT2->GetInverse()); + if (!poInvCT1 || !poInvCT2) + return nullptr; + return std::make_unique(poInvCT2.release(), true, + poInvCT1.release(), true) + .release(); } }; @@ -1302,9 +1351,14 @@ class CompositeCT : public OGRCoordinateTransformation class AxisMappingCoordinateTransformation : public OGRCoordinateTransformation { - public: bool bSwapXY = false; + explicit AxisMappingCoordinateTransformation(bool bSwapXYIn) + : bSwapXY(bSwapXYIn) + { + } + + public: AxisMappingCoordinateTransformation(const std::vector &mappingIn, const std::vector &mappingOut) { @@ -1358,9 +1412,23 @@ class AxisMappingCoordinateTransformation : public OGRCoordinateTransformation return true; } + virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y, + double * /*z*/, double * /*t*/, + int *panErrorCodes) override + { + for (size_t i = 0; i < nCount; i++) + { + if (panErrorCodes) + panErrorCodes[i] = 0; + if (bSwapXY) + std::swap(x[i], y[i]); + } + return true; + } + virtual OGRCoordinateTransformation *GetInverse() const override { - return nullptr; + return new AxisMappingCoordinateTransformation(bSwapXY); } }; @@ -1490,15 +1558,17 @@ class GDALVectorTranslateWrappedDataset : public GDALDataset std::unique_ptr m_poDriverToFree{}; GDALDataset *m_poBase = nullptr; OGRSpatialReference *m_poOutputSRS = nullptr; - bool m_bTransform = false; + const bool m_bTransform = false; std::vector> m_apoLayers{}; - std::vector> m_apoHiddenLayers; + std::vector> m_apoHiddenLayers{}; GDALVectorTranslateWrappedDataset(GDALDataset *poBase, OGRSpatialReference *poOutputSRS, bool bTransform); + CPL_DISALLOW_COPY_ASSIGN(GDALVectorTranslateWrappedDataset) + public: virtual int GetLayerCount() override { @@ -1526,6 +1596,8 @@ class GDALVectorTranslateWrappedLayer : public OGRLayerDecorator std::unique_ptr TranslateFeature(std::unique_ptr poSrcFeat); + CPL_DISALLOW_COPY_ASSIGN(GDALVectorTranslateWrappedLayer) + public: virtual ~GDALVectorTranslateWrappedLayer(); @@ -1770,12 +1842,12 @@ void GDALVectorTranslateWrappedDataset::ReleaseResultSet(OGRLayer *poResultsSet) class OGR2OGRSpatialReferenceHolder { - OGRSpatialReference *m_poSRS; + OGRSpatialReference *m_poSRS = nullptr; + + CPL_DISALLOW_COPY_ASSIGN(OGR2OGRSpatialReferenceHolder) public: - OGR2OGRSpatialReferenceHolder() : m_poSRS(nullptr) - { - } + OGR2OGRSpatialReferenceHolder() = default; ~OGR2OGRSpatialReferenceHolder() { @@ -2835,6 +2907,7 @@ GDALDatasetH GDALVectorTranslate(const char *pszDest, GDALDatasetH hDstDS, oSetup.m_poOutputSRS = oOutputSRSHolder.get(); oSetup.m_bTransform = psOptions->bTransform; oSetup.m_bNullifyOutputSRS = psOptions->bNullifyOutputSRS; + oSetup.m_poUserSourceSRS = poSourceSRS; oSetup.m_bSelFieldsSet = psOptions->bSelFieldsSet; oSetup.m_papszSelFields = psOptions->aosSelFields.List(); oSetup.m_bAppend = bAppend; @@ -3732,8 +3805,8 @@ static OGRwkbGeometryType ConvertType(GeomTypeConversion eGeomTypeConversion, static void DoFieldTypeConversion(GDALDataset *poDstDS, OGRFieldDefn &oFieldDefn, - char **papszFieldTypesToString, - char **papszMapFieldType, + CSLConstList papszFieldTypesToString, + CSLConstList papszMapFieldType, bool bUnsetFieldWidth, bool bQuiet, bool bForceNullable, bool bUnsetDefault) { @@ -3878,13 +3951,87 @@ static void DoFieldTypeConversion(GDALDataset *poDstDS, } } +/************************************************************************/ +/* GetArrowGeomFieldIndex() */ +/************************************************************************/ + +static int GetArrowGeomFieldIndex(const struct ArrowSchema *psLayerSchema, + const char *pszFieldName) +{ + if (strcmp(psLayerSchema->format, "+s") == 0) // struct + { + for (int i = 0; i < psLayerSchema->n_children; ++i) + { + const auto psSchema = psLayerSchema->children[i]; + if (strcmp(psSchema->format, "z") == 0) // binary + { + if (strcmp(psSchema->name, pszFieldName) == 0) + { + return i; + } + else + { + // Check if ARROW:extension:name = ogc.wkb or geoarrow.wkb + const char *pabyMetadata = psSchema->metadata; + if (pabyMetadata) + { + const auto oMetadata = + OGRParseArrowMetadata(pabyMetadata); + auto oIter = oMetadata.find(ARROW_EXTENSION_NAME_KEY); + if (oIter != oMetadata.end() && + (oIter->second == EXTENSION_NAME_OGC_WKB || + oIter->second == EXTENSION_NAME_GEOARROW_WKB)) + { + return i; + } + } + } + } + } + } + return -1; +} + +/************************************************************************/ +/* BuildGetArrowStreamOptions() */ +/************************************************************************/ + +static CPLStringList +BuildGetArrowStreamOptions(const GDALVectorTranslateOptions *psOptions, + bool bPreserveFID) +{ + CPLStringList aosOptionsGetArrowStream; + aosOptionsGetArrowStream.SetNameValue("SILENCE_GET_SCHEMA_ERROR", "YES"); + aosOptionsGetArrowStream.SetNameValue("GEOMETRY_ENCODING", "WKB"); + if (!bPreserveFID) + aosOptionsGetArrowStream.SetNameValue("INCLUDE_FID", "NO"); + if (psOptions->nLimit >= 0) + { + aosOptionsGetArrowStream.SetNameValue( + "MAX_FEATURES_IN_BATCH", + CPLSPrintf(CPL_FRMT_GIB, + std::min(psOptions->nLimit, + (psOptions->nGroupTransactions > 0 + ? psOptions->nGroupTransactions + : 65536)))); + } + else if (psOptions->nGroupTransactions > 0) + { + aosOptionsGetArrowStream.SetNameValue( + "MAX_FEATURES_IN_BATCH", + CPLSPrintf("%d", psOptions->nGroupTransactions)); + } + return aosOptionsGetArrowStream; +} + /************************************************************************/ /* SetupTargetLayer::CanUseWriteArrowBatch() */ /************************************************************************/ bool SetupTargetLayer::CanUseWriteArrowBatch( OGRLayer *poSrcLayer, OGRLayer *poDstLayer, bool bJustCreatedLayer, - const GDALVectorTranslateOptions *psOptions, bool &bError) + const GDALVectorTranslateOptions *psOptions, bool bPreserveFID, + bool &bError, OGRArrowArrayStream &streamSrc) { bError = false; @@ -3905,11 +4052,11 @@ bool SetupTargetLayer::CanUseWriteArrowBatch( !psOptions->aosLCO.FetchNameValue("BATCH_SIZE") && CPLTestBool(CPLGetConfigOption("OGR2OGR_USE_ARROW_API", "YES"))) || CPLTestBool(CPLGetConfigOption("OGR2OGR_USE_ARROW_API", "NO"))) && - !psOptions->bSkipFailures && !psOptions->bTransform && - !psOptions->poClipSrc && !psOptions->poClipDst && - psOptions->oGCPs.nGCPCount == 0 && !psOptions->bWrapDateline && - !m_papszSelFields && !m_bAddMissingFields && - m_eGType == GEOMTYPE_UNCHANGED && psOptions->eGeomOp == GEOMOP_NONE && + !psOptions->bSkipFailures && !psOptions->poClipSrc && + !psOptions->poClipDst && psOptions->oGCPs.nGCPCount == 0 && + !psOptions->bWrapDateline && !m_papszSelFields && + !m_bAddMissingFields && m_eGType == GEOMTYPE_UNCHANGED && + psOptions->eGeomOp == GEOMOP_NONE && m_eGeomTypeConversion == GTC_DEFAULT && m_nCoordDim < 0 && !m_papszFieldTypesToString && !m_papszMapFieldType && !m_bUnsetFieldWidth && !m_bExplodeCollections && !m_pszZField && @@ -3918,14 +4065,43 @@ bool SetupTargetLayer::CanUseWriteArrowBatch( psOptions->dfXYRes == OGRGeomCoordinatePrecision::UNKNOWN && !psOptions->bMakeValid && !psOptions->bSkipInvalidGeom) { - struct ArrowArrayStream streamSrc; - const char *const apszOptions[] = {"SILENCE_GET_SCHEMA_ERROR=YES", - nullptr}; - if (poSrcLayer->GetArrowStream(&streamSrc, apszOptions)) + if (psOptions->bTransform) + { + // To simplify implementation for now + if (poSrcLayer->GetLayerDefn()->GetGeomFieldCount() != 1 || + poDstLayer->GetLayerDefn()->GetGeomFieldCount() != 1) + { + return false; + } + auto poSrcSRS = m_poUserSourceSRS ? m_poUserSourceSRS + : poSrcLayer->GetLayerDefn() + ->GetGeomFieldDefn(0) + ->GetSpatialRef(); + if (!poSrcSRS || + !OGRGeometryFactory::isTransformWithOptionsRegularTransform( + poSrcSRS, m_poOutputSRS, nullptr)) + { + return false; + } + } + + const CPLStringList aosGetArrowStreamOptions( + BuildGetArrowStreamOptions(psOptions, bPreserveFID)); + if (poSrcLayer->GetArrowStream(streamSrc.get(), + aosGetArrowStreamOptions.List())) { struct ArrowSchema schemaSrc; - if (streamSrc.get_schema(&streamSrc, &schemaSrc) == 0) + if (streamSrc.get_schema(&schemaSrc) == 0) { + if (psOptions->bTransform && + GetArrowGeomFieldIndex(&schemaSrc, + poSrcLayer->GetGeometryColumn()) < 0) + { + schemaSrc.release(&schemaSrc); + streamSrc.clear(); + return false; + } + std::string osErrorMsg; if (poDstLayer->IsArrowSchemaSupported(&schemaSrc, nullptr, osErrorMsg)) @@ -4004,7 +4180,7 @@ bool SetupTargetLayer::CanUseWriteArrowBatch( "Cannot create field %s", pszFieldName); schemaSrc.release(&schemaSrc); - streamSrc.release(&streamSrc); + streamSrc.clear(); return false; } } @@ -4016,7 +4192,8 @@ bool SetupTargetLayer::CanUseWriteArrowBatch( // check that it looks to be the same as the source // one struct ArrowArrayStream streamDst; - if (poDstLayer->GetArrowStream(&streamDst, nullptr)) + if (poDstLayer->GetArrowStream( + &streamDst, aosGetArrowStreamOptions.List())) { struct ArrowSchema schemaDst; if (streamDst.get_schema(&streamDst, &schemaDst) == @@ -4047,7 +4224,8 @@ bool SetupTargetLayer::CanUseWriteArrowBatch( } schemaSrc.release(&schemaSrc); } - streamSrc.release(&streamSrc); + if (!bUseWriteArrowBatch) + streamSrc.clear(); } } return bUseWriteArrowBatch; @@ -4729,9 +4907,11 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, std::map oMapResolved; /* Determine if NUMERIC field width narrowing is allowed */ + auto poSrcDriver = m_poSrcDS->GetDriver(); const char *pszSrcWidthIncludesDecimalSeparator{ - m_poSrcDS->GetDriver()->GetMetadataItem( - "DMD_NUMERIC_FIELD_WIDTH_INCLUDES_DECIMAL_SEPARATOR")}; + poSrcDriver ? poSrcDriver->GetMetadataItem( + "DMD_NUMERIC_FIELD_WIDTH_INCLUDES_DECIMAL_SEPARATOR") + : nullptr}; const bool bSrcWidthIncludesDecimalSeparator{ pszSrcWidthIncludesDecimalSeparator && EQUAL(pszSrcWidthIncludesDecimalSeparator, "YES")}; @@ -4742,8 +4922,9 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, pszDstWidthIncludesDecimalSeparator && EQUAL(pszDstWidthIncludesDecimalSeparator, "YES")}; const char *pszSrcWidthIncludesMinusSign{ - m_poSrcDS->GetDriver()->GetMetadataItem( - "DMD_NUMERIC_FIELD_WIDTH_INCLUDES_SIGN")}; + poSrcDriver ? poSrcDriver->GetMetadataItem( + "DMD_NUMERIC_FIELD_WIDTH_INCLUDES_SIGN") + : nullptr}; const bool bSrcWidthIncludesMinusSign{ pszSrcWidthIncludesMinusSign && EQUAL(pszSrcWidthIncludesMinusSign, "YES")}; @@ -4774,8 +4955,10 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, } bool bError = false; - const bool bUseWriteArrowBatch = CanUseWriteArrowBatch( - poSrcLayer, poDstLayer, bJustCreatedLayer, psOptions, bError); + OGRArrowArrayStream streamSrc; + const bool bUseWriteArrowBatch = + CanUseWriteArrowBatch(poSrcLayer, poDstLayer, bJustCreatedLayer, + psOptions, bPreserveFID, bError, streamSrc); if (bError) return nullptr; @@ -5211,10 +5394,31 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, if (iDstField >= 0) anMap[iField] = iDstField; else + { + if (m_bExactFieldNameMatch) + { + const int iDstFieldCandidate = poDstLayer->FindFieldIndex( + poSrcFieldDefn->GetNameRef(), false); + if (iDstFieldCandidate >= 0) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Source field '%s' could have been identified " + "with existing field '%s' of destination " + "layer '%s' if the -relaxedFieldNameMatch " + "option had been specified.", + poSrcFieldDefn->GetNameRef(), + poDstLayer->GetLayerDefn() + ->GetFieldDefn(iDstFieldCandidate) + ->GetNameRef(), + poDstLayer->GetName()); + } + } + CPLDebug( "GDALVectorTranslate", "Skipping field '%s' not found in destination layer '%s'.", poSrcFieldDefn->GetNameRef(), poDstLayer->GetName()); + } } } @@ -5237,7 +5441,7 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, nTotalEventsDone = 0; } - std::unique_ptr psInfo(new TargetLayerInfo); + auto psInfo = std::make_unique(); psInfo->m_bUseWriteArrowBatch = bUseWriteArrowBatch; psInfo->m_nFeaturesRead = 0; psInfo->m_bPerFeatureCT = false; @@ -5334,6 +5538,8 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName, psInfo->m_bSupportCurves = CPL_TO_BOOL(poDstLayer->TestCapability(OLCCurveGeometries)); + psInfo->m_sArrowArrayStream = std::move(streamSrc); + return psInfo; } @@ -5624,65 +5830,77 @@ SetupCT(TargetLayerInfo *psInfo, OGRLayer *poSrcLayer, bool bTransform, /************************************************************************/ bool LayerTranslator::TranslateArrow( - const TargetLayerInfo *psInfo, GIntBig nCountLayerFeatures, + TargetLayerInfo *psInfo, GIntBig nCountLayerFeatures, GIntBig *pnReadFeatureCount, GDALProgressFunc pfnProgress, void *pProgressArg, const GDALVectorTranslateOptions *psOptions) { - struct ArrowArrayStream stream; struct ArrowSchema schema; - CPLStringList aosOptionsGetArrowStream; CPLStringList aosOptionsWriteArrowBatch; - aosOptionsGetArrowStream.SetNameValue("GEOMETRY_ENCODING", "WKB"); - if (!psInfo->m_bPreserveFID) - aosOptionsGetArrowStream.SetNameValue("INCLUDE_FID", "NO"); - else + if (psInfo->m_bPreserveFID) { aosOptionsWriteArrowBatch.SetNameValue( "FID", psInfo->m_poSrcLayer->GetFIDColumn()); aosOptionsWriteArrowBatch.SetNameValue("IF_FID_NOT_PRESERVED", "WARNING"); } - if (psOptions->nLimit >= 0) - { - aosOptionsGetArrowStream.SetNameValue( - "MAX_FEATURES_IN_BATCH", - CPLSPrintf(CPL_FRMT_GIB, - std::min(psOptions->nLimit, - (psOptions->nGroupTransactions > 0 - ? psOptions->nGroupTransactions - : 65536)))); - } - else if (psOptions->nGroupTransactions > 0) + + if (psInfo->m_sArrowArrayStream.get_schema(&schema) != 0) { - aosOptionsGetArrowStream.SetNameValue( - "MAX_FEATURES_IN_BATCH", - CPLSPrintf("%d", psOptions->nGroupTransactions)); + CPLError(CE_Failure, CPLE_AppDefined, "stream.get_schema() failed"); + return false; } - if (psInfo->m_poSrcLayer->GetArrowStream(&stream, - aosOptionsGetArrowStream.List())) + + int iArrowGeomFieldIndex = -1; + if (m_bTransform) { - if (stream.get_schema(&stream, &schema) != 0) + iArrowGeomFieldIndex = GetArrowGeomFieldIndex( + &schema, psInfo->m_poSrcLayer->GetGeometryColumn()); + if (!SetupCT(psInfo, psInfo->m_poSrcLayer, m_bTransform, + m_bWrapDateline, m_osDateLineOffset, m_poUserSourceSRS, + nullptr, m_poOutputSRS, m_poGCPCoordTrans, false)) { - CPLError(CE_Failure, CPLE_AppDefined, "stream.get_schema() failed"); - stream.release(&stream); return false; } } - else - { - CPLError(CE_Failure, CPLE_AppDefined, "GetArrowStream() failed"); - return false; - } bool bRet = true; GIntBig nCount = 0; bool bGoOn = true; + std::vector abyModifiedWKB; + const int nNumReprojectionThreads = []() + { + const int nNumCPUs = CPLGetNumCPUs(); + if (nNumCPUs <= 1) + { + return 1; + } + else + { + const char *pszNumThreads = + CPLGetConfigOption("GDAL_NUM_THREADS", nullptr); + if (pszNumThreads) + { + if (EQUAL(pszNumThreads, "ALL_CPUS")) + return CPLGetNumCPUs(); + return std::min(atoi(pszNumThreads), 1024); + } + else + { + return std::max(2, nNumCPUs / 2); + } + } + }(); + + // Somewhat arbitrary threshold (config option only/mostly for autotest purposes) + const int MIN_FEATURES_FOR_THREADED_REPROJ = atoi(CPLGetConfigOption( + "OGR2OGR_MIN_FEATURES_FOR_THREADED_REPROJ", "10000")); + while (bGoOn) { struct ArrowArray array; // Acquire source batch - if (stream.get_next(&stream, &array) != 0) + if (psInfo->m_sArrowArrayStream.get_next(&array) != 0) { CPLError(CE_Failure, CPLE_AppDefined, "stream.get_next() failed"); bRet = false; @@ -5714,20 +5932,155 @@ bool LayerTranslator::TranslateArrow( nCount += array.length; } + const auto nArrayLength = array.length; + + // Coordinate reprojection + if (m_bTransform) + { + struct GeomArrayReleaser + { + const void *origin_buffers_2 = nullptr; + void (*origin_release)(struct ArrowArray *) = nullptr; + void *origin_private_data = nullptr; + + static void init(struct ArrowArray *psGeomArray) + { + GeomArrayReleaser *releaser = new GeomArrayReleaser(); + CPLAssert(psGeomArray->n_buffers >= 3); + releaser->origin_buffers_2 = psGeomArray->buffers[2]; + releaser->origin_private_data = psGeomArray->private_data; + releaser->origin_release = psGeomArray->release; + psGeomArray->release = GeomArrayReleaser::release; + psGeomArray->private_data = releaser; + } + + static void release(struct ArrowArray *psGeomArray) + { + GeomArrayReleaser *releaser = + static_cast( + psGeomArray->private_data); + psGeomArray->buffers[2] = releaser->origin_buffers_2; + psGeomArray->private_data = releaser->origin_private_data; + psGeomArray->release = releaser->origin_release; + if (psGeomArray->release) + psGeomArray->release(psGeomArray); + delete releaser; + } + }; + + auto *psGeomArray = array.children[iArrowGeomFieldIndex]; + GeomArrayReleaser::init(psGeomArray); + + GByte *pabyWKB = static_cast( + const_cast(psGeomArray->buffers[2])); + const uint32_t *panOffsets = + static_cast(psGeomArray->buffers[1]); + auto poCT = psInfo->m_aoReprojectionInfo[0].m_poCT.get(); + + try + { + abyModifiedWKB.resize(panOffsets[nArrayLength]); + } + catch (const std::exception &) + { + CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory"); + bRet = false; + if (array.release) + array.release(&array); + break; + } + memcpy(abyModifiedWKB.data(), pabyWKB, panOffsets[nArrayLength]); + psGeomArray->buffers[2] = abyModifiedWKB.data(); + + std::atomic atomicRet{true}; + const auto oReprojectionLambda = + [psGeomArray, nArrayLength, panOffsets, &atomicRet, + &abyModifiedWKB, &poCT](int iThread, int nThreads) + { + OGRWKBTransformCache oCache; + OGREnvelope3D sEnv3D; + auto poThisCT = + std::unique_ptr(poCT->Clone()); + if (!poThisCT) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot clone OGRCoordinateTransformation"); + atomicRet = false; + return; + } + + const GByte *pabyValidity = + static_cast(psGeomArray->buffers[0]); + const size_t iStart = + static_cast(iThread * nArrayLength / nThreads); + const size_t iMax = static_cast( + (iThread + 1) * nArrayLength / nThreads); + for (size_t i = iStart; i < iMax; ++i) + { + const size_t iShifted = + static_cast(i + psGeomArray->offset); + if (!pabyValidity || (pabyValidity[iShifted >> 8] & + (1 << (iShifted % 8))) != 0) + { + const auto nWKBSize = + panOffsets[iShifted + 1] - panOffsets[iShifted]; + if (!OGRWKBTransform( + abyModifiedWKB.data() + panOffsets[iShifted], + nWKBSize, poThisCT.get(), oCache, sEnv3D)) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Reprojection failed"); + atomicRet = false; + break; + } + } + } + }; + + if (nArrayLength >= MIN_FEATURES_FOR_THREADED_REPROJ && + nNumReprojectionThreads >= 2) + { + std::vector> oTasks; + for (int iThread = 0; iThread < nNumReprojectionThreads; + ++iThread) + { + oTasks.emplace_back(std::async(std::launch::async, + oReprojectionLambda, iThread, + nNumReprojectionThreads)); + } + for (auto &oTask : oTasks) + { + oTask.get(); + } + } + else + { + oReprojectionLambda(0, 1); + } + + bRet = atomicRet; + if (!bRet) + { + if (array.release) + array.release(&array); + break; + } + } + // Write batch to target layer - if (!psInfo->m_poDstLayer->WriteArrowBatch( - &schema, &array, aosOptionsWriteArrowBatch.List())) + const bool bWriteOK = psInfo->m_poDstLayer->WriteArrowBatch( + &schema, &array, aosOptionsWriteArrowBatch.List()); + + if (array.release) + array.release(&array); + + if (!bWriteOK) { CPLError(CE_Failure, CPLE_AppDefined, "WriteArrowBatch() failed"); - if (array.release) - array.release(&array); bRet = false; break; } - if (array.release) - array.release(&array); - /* Report progress */ if (pfnProgress) { @@ -5747,47 +6100,6 @@ bool LayerTranslator::TranslateArrow( schema.release(&schema); - // Ugly hack to work around https://github.com/OSGeo/gdal/issues/9497 - // Deleting a RecordBatchReader obtained from arrow::dataset::Scanner.ToRecordBatchReader() - // is a lengthy operation since all batches are read in its destructors. - // Here we ask to our custom I/O layer to return in error to short circuit - // that lengthy operation. - if (auto poDS = psInfo->m_poSrcLayer->GetDataset()) - { - if (poDS->GetLayerCount() == 1 && poDS->GetDriver() && - EQUAL(poDS->GetDriver()->GetDescription(), "PARQUET")) - { - bool bStopIO = false; - const char *pszArrowStopIO = - CPLGetConfigOption("OGR_ARROW_STOP_IO", nullptr); - if (pszArrowStopIO && CPLTestBool(pszArrowStopIO)) - { - bStopIO = true; - } - else if (!pszArrowStopIO) - { - std::string osExePath; - osExePath.resize(1024); - if (CPLGetExecPath(osExePath.data(), - static_cast(osExePath.size()))) - { - osExePath.resize(strlen(osExePath.data())); - if (strcmp(CPLGetBasename(osExePath.data()), "ogr2ogr") == - 0) - { - bStopIO = true; - } - } - } - if (bStopIO) - { - CPLSetConfigOption("OGR_ARROW_STOP_IO", "YES"); - CPLDebug("OGR2OGR", "Forcing interruption of Parquet I/O"); - } - } - } - - stream.release(&stream); return bRet; } @@ -5911,9 +6223,9 @@ bool LayerTranslator::Translate( int nIters = 1; std::unique_ptr poCollToExplode; int iGeomCollToExplode = -1; + OGRGeometry *poSrcGeometry = nullptr; if (bExplodeCollections) { - OGRGeometry *poSrcGeometry; if (iRequestedSrcGeomField >= 0) poSrcGeometry = poFeature->GetGeomFieldRef(iRequestedSrcGeomField); @@ -5925,7 +6237,9 @@ bool LayerTranslator::Translate( { const int nParts = poSrcGeometry->toGeometryCollection()->getNumGeometries(); - if (nParts > 0) + if (nParts > 0 || + wkbFlatten(poSrcGeometry->getGeometryType()) != + wkbGeometryCollection) { iGeomCollToExplode = iRequestedSrcGeomField >= 0 ? iRequestedSrcGeomField @@ -5933,7 +6247,7 @@ bool LayerTranslator::Translate( poCollToExplode.reset( poFeature->StealGeometry(iGeomCollToExplode) ->toGeometryCollection()); - nIters = nParts; + nIters = std::max(1, nParts); } } } @@ -6150,9 +6464,46 @@ bool LayerTranslator::Translate( if (poCollToExplode && iGeom == iGeomCollToExplode) { - OGRGeometry *poPart = poCollToExplode->getGeometryRef(0); - poCollToExplode->removeGeometry(0, FALSE); - poDstGeometry.reset(poPart); + if (poSrcGeometry && poCollToExplode->IsEmpty()) + { + const OGRwkbGeometryType eSrcType = + poSrcGeometry->getGeometryType(); + const OGRwkbGeometryType eSrcFlattenType = + wkbFlatten(eSrcType); + OGRwkbGeometryType eDstType = eSrcType; + switch (eSrcFlattenType) + { + case wkbMultiPoint: + eDstType = wkbPoint; + break; + case wkbMultiLineString: + eDstType = wkbLineString; + break; + case wkbMultiPolygon: + eDstType = wkbPolygon; + break; + case wkbMultiCurve: + eDstType = wkbCompoundCurve; + break; + case wkbMultiSurface: + eDstType = wkbCurvePolygon; + break; + default: + break; + } + eDstType = + OGR_GT_SetModifier(eDstType, OGR_GT_HasZ(eSrcType), + OGR_GT_HasM(eSrcType)); + poDstGeometry.reset( + OGRGeometryFactory::createGeometry(eDstType)); + } + else + { + OGRGeometry *poPart = + poCollToExplode->getGeometryRef(0); + poCollToExplode->removeGeometry(0, FALSE); + poDstGeometry.reset(poPart); + } } else { @@ -7256,22 +7607,16 @@ static std::unique_ptr GDALVectorTranslateOptionsGetParser( argParser->add_argument("-segmentize") .metavar("") - .action( - [psOptions](const std::string &s) - { - psOptions->eGeomOp = GEOMOP_SEGMENTIZE; - psOptions->dfGeomOpParam = CPLAtofM(s.c_str()); - }) + .store_into(psOptions->dfGeomOpParam) + .action([psOptions](const std::string &) + { psOptions->eGeomOp = GEOMOP_SEGMENTIZE; }) .help(_("Maximum distance between 2 nodes.")); argParser->add_argument("-simplify") .metavar("") - .action( - [psOptions](const std::string &s) - { - psOptions->eGeomOp = GEOMOP_SIMPLIFY_PRESERVE_TOPOLOGY; - psOptions->dfGeomOpParam = CPLAtofM(s.c_str()); - }) + .store_into(psOptions->dfGeomOpParam) + .action([psOptions](const std::string &) + { psOptions->eGeomOp = GEOMOP_SIMPLIFY_PRESERVE_TOPOLOGY; }) .help(_("Distance tolerance for simplification.")); argParser->add_argument("-makevalid") diff --git a/apps/ogrdissolve.cpp b/apps/ogrdissolve.cpp deleted file mode 100644 index cf79c595b60c..000000000000 --- a/apps/ogrdissolve.cpp +++ /dev/null @@ -1,1227 +0,0 @@ -/****************************************************************************** - * - * Project: OpenGIS Simple Features Reference Implementation - * Purpose: Allow a user to dissolve geometries based on an attribute. - * Author: Howard Butler, hobu.inc@gmail.com - * - ****************************************************************************** - * Copyright (c) 2007, Howard Butler - * - * 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. - ****************************************************************************/ - -#include "ogrsf_frmts.h" -#include "ogr_p.h" -#include "cpl_conv.h" -#include "cpl_string.h" -#include "ogr_api.h" -#include "commonutils.h" -#include -#include - -static void Usage(); - -static int DissolveLayer(OGRDataSource *poSrcDS, OGRLayer *poSrcLayer, - OGRDataSource *poDstDS, char **papszLSCO, - const char *pszNewLayerName, int bTransform, - OGRSpatialReference *poOutputSRS, - OGRSpatialReference *poSourceSRS, - char **papszSelFields, int bAppend, int eGType, - int bOverwrite); - -static int bSkipFailures = FALSE; -static int nGroupTransactions = 200; -static int bPreserveFID = FALSE; -static int nFIDToFetch = OGRNullFID; - -typedef std::multimap StringGeometryMMap; -typedef std::map StringGeometryColMap; -typedef std::map StringGeometryMap; -typedef std::list GeometriesList; - -/************************************************************************/ -/* main() */ -/************************************************************************/ - -MAIN_START(nArgc, papszArgv) - -{ - const char *pszFormat = "ESRI Shapefile"; - const char *pszDataSource = NULL; - const char *pszDestDataSource = NULL; - char **papszLayers = NULL; - char **papszDSCO = NULL, **papszLCO = NULL; - int bTransform = FALSE; - int bAppend = FALSE, bUpdate = FALSE, bOverwrite = FALSE; - const char *pszOutputSRSDef = NULL; - const char *pszSourceSRSDef = NULL; - OGRSpatialReference *poOutputSRS = NULL; - OGRSpatialReference *poSourceSRS = NULL; - const char *pszNewLayerName = NULL; - const char *pszWHERE = NULL; - OGRGeometry *poSpatialFilter = NULL; - const char *pszSelect; - char **papszSelFields = NULL; - const char *pszSQLStatement = NULL; - int eGType = -2; - - /* -------------------------------------------------------------------- */ - /* Register format(s). */ - /* -------------------------------------------------------------------- */ - OGRRegisterAll(); - - /* -------------------------------------------------------------------- */ - /* Processing command line arguments. */ - /* -------------------------------------------------------------------- */ - nArgc = OGRGeneralCmdLineProcessor(nArgc, &papszArgv, 0); - - if (nArgc < 1) - exit(-nArgc); - - for (int iArg = 1; iArg < nArgc; iArg++) - { - if (EQUAL(papszArgv[iArg], "--help")) - { - Usage(); - } - if ((EQUAL(papszArgv[iArg], "-f") || EQUAL(papszArgv[iArg], "-of")) && - iArg < nArgc - 1) - { - pszFormat = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-dsco") && iArg < nArgc - 1) - { - papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg]); - } - else if (EQUAL(papszArgv[iArg], "-lco") && iArg < nArgc - 1) - { - papszLCO = CSLAddString(papszLCO, papszArgv[++iArg]); - } - else if (EQUAL(papszArgv[iArg], "-preserve_fid")) - { - bPreserveFID = TRUE; - } - else if (STARTS_WITH_CI(papszArgv[iArg], "-skip")) - { - bSkipFailures = TRUE; - } - else if (EQUAL(papszArgv[iArg], "-append")) - { - bAppend = TRUE; - } - else if (EQUAL(papszArgv[iArg], "-overwrite")) - { - bOverwrite = TRUE; - } - else if (EQUAL(papszArgv[iArg], "-update")) - { - bUpdate = TRUE; - } - else if (EQUAL(papszArgv[iArg], "-fid") && papszArgv[iArg + 1] != NULL) - { - nFIDToFetch = atoi(papszArgv[++iArg]); - } - else if (EQUAL(papszArgv[iArg], "-sql") && papszArgv[iArg + 1] != NULL) - { - pszSQLStatement = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-nln") && iArg < nArgc - 1) - { - pszNewLayerName = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-nlt") && iArg < nArgc - 1) - { - int bIs3D = FALSE; - CPLString osGeomName = papszArgv[iArg + 1]; - if (strlen(papszArgv[iArg + 1]) > 3 && - STARTS_WITH_CI(papszArgv[iArg + 1] + - strlen(papszArgv[iArg + 1]) - 3, - "25D")) - { - bIs3D = TRUE; - osGeomName.resize(osGeomName.size() - 3); - } - else if (strlen(papszArgv[iArg + 1]) > 1 && - STARTS_WITH_CI(papszArgv[iArg + 1] + - strlen(papszArgv[iArg + 1]) - 1, - "Z")) - { - bIs3D = TRUE; - osGeomName.pop_back(); - } - if (EQUAL(osGeomName, "NONE")) - eGType = wkbNone; - else if (EQUAL(osGeomName, "GEOMETRY")) - eGType = wkbUnknown; - else - { - eGType = OGRFromOGCGeomType(osGeomName); - if (eGType == wkbUnknown) - { - fprintf(stderr, "-nlt %s: type not recognised.\n", - papszArgv[iArg + 1]); - exit(1); - } - } - if (eGType != wkbNone && bIs3D) - eGType = wkbSetZ((OGRwkbGeometryType)eGType); - iArg++; - } - else if (EQUAL(papszArgv[iArg], "-tg") && iArg < nArgc - 1) - { - nGroupTransactions = atoi(papszArgv[++iArg]); - } - else if (EQUAL(papszArgv[iArg], "-s_srs") && iArg < nArgc - 1) - { - pszSourceSRSDef = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-a_srs") && iArg < nArgc - 1) - { - pszOutputSRSDef = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-t_srs") && iArg < nArgc - 1) - { - pszOutputSRSDef = papszArgv[++iArg]; - bTransform = TRUE; - } - else if (EQUAL(papszArgv[iArg], "-spat") && - papszArgv[iArg + 1] != NULL && papszArgv[iArg + 2] != NULL && - papszArgv[iArg + 3] != NULL && papszArgv[iArg + 4] != NULL) - { - OGRLinearRing oRing; - - oRing.addPoint(CPLAtof(papszArgv[iArg + 1]), - CPLAtof(papszArgv[iArg + 2])); - oRing.addPoint(CPLAtof(papszArgv[iArg + 1]), - CPLAtof(papszArgv[iArg + 4])); - oRing.addPoint(CPLAtof(papszArgv[iArg + 3]), - CPLAtof(papszArgv[iArg + 4])); - oRing.addPoint(CPLAtof(papszArgv[iArg + 3]), - CPLAtof(papszArgv[iArg + 2])); - oRing.addPoint(CPLAtof(papszArgv[iArg + 1]), - CPLAtof(papszArgv[iArg + 2])); - - poSpatialFilter = new OGRPolygon(); - poSpatialFilter->toPolygon()->addRing(&oRing); - iArg += 4; - } - else if (EQUAL(papszArgv[iArg], "-where") && - papszArgv[iArg + 1] != NULL) - { - pszWHERE = papszArgv[++iArg]; - } - else if (EQUAL(papszArgv[iArg], "-select") && - papszArgv[iArg + 1] != NULL) - { - pszSelect = papszArgv[++iArg]; - papszSelFields = - CSLTokenizeStringComplex(pszSelect, " ,", FALSE, FALSE); - } - else if (papszArgv[iArg][0] == '-') - { - Usage(); - } - else if (pszDestDataSource == NULL) - pszDestDataSource = papszArgv[iArg]; - else if (pszDataSource == NULL) - pszDataSource = papszArgv[iArg]; - else - papszLayers = CSLAddString(papszLayers, papszArgv[iArg]); - } - - if (pszDataSource == NULL) - Usage(); - - /* -------------------------------------------------------------------- */ - /* Open data source. */ - /* -------------------------------------------------------------------- */ - OGRDataSource *poDS; - - poDS = OGRSFDriverRegistrar::Open(pszDataSource, FALSE); - - /* -------------------------------------------------------------------- */ - /* Report failure */ - /* -------------------------------------------------------------------- */ - if (poDS == NULL) - { - OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); - - printf("FAILURE:\n" - "Unable to open datasource `%s' with the following drivers.\n", - pszDataSource); - - for (int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++) - { - printf(" -> %s\n", poR->GetDriver(iDriver)->GetName()); - } - - exit(1); - } - - /* -------------------------------------------------------------------- */ - /* Try opening the output datasource as an existing, writable */ - /* -------------------------------------------------------------------- */ - OGRDataSource *poODS; - - if (bUpdate) - { - poODS = OGRSFDriverRegistrar::Open(pszDestDataSource, TRUE); - if (poODS == NULL) - { - printf("FAILURE:\n" - "Unable to open existing output datasource `%s'.\n", - pszDestDataSource); - exit(1); - } - } - - /* -------------------------------------------------------------------- */ - /* Find the output driver. */ - /* -------------------------------------------------------------------- */ - else - { - OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); - OGRSFDriver *poDriver = NULL; - int iDriver; - - for (iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; - iDriver++) - { - if (EQUAL(poR->GetDriver(iDriver)->GetName(), pszFormat)) - { - poDriver = poR->GetDriver(iDriver); - } - } - - if (poDriver == NULL) - { - printf("Unable to find driver `%s'.\n", pszFormat); - printf("The following drivers are available:\n"); - - for (iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++) - { - printf(" -> `%s'\n", poR->GetDriver(iDriver)->GetName()); - } - exit(1); - } - - if (!poDriver->TestCapability(ODrCCreateDataSource)) - { - printf("%s driver does not support data source creation.\n", - pszFormat); - exit(1); - } - - /* -------------------------------------------------------------------- - */ - /* Create the output data source. */ - /* -------------------------------------------------------------------- - */ - poODS = poDriver->CreateDataSource(pszDestDataSource, papszDSCO); - if (poODS == NULL) - { - printf("%s driver failed to create %s\n", pszFormat, - pszDestDataSource); - exit(1); - } - } - - /* -------------------------------------------------------------------- */ - /* Parse the output SRS definition if possible. */ - /* -------------------------------------------------------------------- */ - if (pszOutputSRSDef != NULL) - { - poOutputSRS = new OGRSpatialReference(); - poOutputSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - if (poOutputSRS->SetFromUserInput(pszOutputSRSDef) != OGRERR_NONE) - { - printf("Failed to process SRS definition: %s\n", pszOutputSRSDef); - exit(1); - } - } - - /* -------------------------------------------------------------------- */ - /* Parse the source SRS definition if possible. */ - /* -------------------------------------------------------------------- */ - if (pszSourceSRSDef != NULL) - { - poSourceSRS = new OGRSpatialReference(); - poSourceSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - if (poSourceSRS->SetFromUserInput(pszSourceSRSDef) != OGRERR_NONE) - { - printf("Failed to process SRS definition: %s\n", pszSourceSRSDef); - exit(1); - } - } - - /* -------------------------------------------------------------------- */ - /* Special case for -sql clause. No source layers required. */ - /* -------------------------------------------------------------------- */ - if (pszSQLStatement != NULL) - { - OGRLayer *poResultSet; - - if (pszWHERE != NULL) - printf("-where clause ignored in combination with -sql.\n"); - if (CSLCount(papszLayers) > 0) - printf("layer names ignored in combination with -sql.\n"); - - poResultSet = poDS->ExecuteSQL(pszSQLStatement, poSpatialFilter, NULL); - - if (poResultSet != NULL) - { - if (!DissolveLayer(poDS, poResultSet, poODS, papszLCO, - pszNewLayerName, bTransform, poOutputSRS, - poSourceSRS, papszSelFields, bAppend, eGType, - bOverwrite)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "Terminating translation prematurely after failed\n" - "translation from sql statement."); - - exit(1); - } - poDS->ReleaseResultSet(poResultSet); - } - } - - /* -------------------------------------------------------------------- */ - /* Process each data source layer. */ - /* -------------------------------------------------------------------- */ - for (int iLayer = 0; - pszSQLStatement == NULL && iLayer < poDS->GetLayerCount(); iLayer++) - { - OGRLayer *poLayer = poDS->GetLayer(iLayer); - - if (poLayer == NULL) - { - printf("FAILURE: Couldn't fetch advertised layer %d!\n", iLayer); - exit(1); - } - - if (CSLCount(papszLayers) == 0 || - CSLFindString(papszLayers, poLayer->GetLayerDefn()->GetName()) != - -1) - { - if (pszWHERE != NULL) - poLayer->SetAttributeFilter(pszWHERE); - - if (poSpatialFilter != NULL) - poLayer->SetSpatialFilter(poSpatialFilter); - - if (!DissolveLayer(poDS, poLayer, poODS, papszLCO, pszNewLayerName, - bTransform, poOutputSRS, poSourceSRS, - papszSelFields, bAppend, eGType, bOverwrite) && - !bSkipFailures) - { - CPLError(CE_Failure, CPLE_AppDefined, - "Terminating translation prematurely after failed\n" - "translation of layer %s\n", - poLayer->GetLayerDefn()->GetName()); - - exit(1); - } - } - } - - /* -------------------------------------------------------------------- */ - /* Close down. */ - /* -------------------------------------------------------------------- */ - OGRSpatialReference::DestroySpatialReference(poOutputSRS); - OGRSpatialReference::DestroySpatialReference(poSourceSRS); - OGRDataSource::DestroyDataSource(poODS); - OGRDataSource::DestroyDataSource(poDS); - - CSLDestroy(papszSelFields); - CSLDestroy(papszArgv); - CSLDestroy(papszLayers); - CSLDestroy(papszDSCO); - CSLDestroy(papszLCO); - - OGRCleanupAll(); - -#ifdef DBMALLOC - malloc_dump(1); -#endif - - return 0; -} - -MAIN_END - -/************************************************************************/ -/* Usage() */ -/************************************************************************/ - -static void Usage() - -{ - OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); - - printf("Usage: ogr2ogr [--help] [--help-general]\n" - " [-skipfailures] [-append] [-update]\n" - " [-select field_list] [-where restricted_where] \n" - " [-sql ] \n" - " [-spat xmin ymin xmax ymax] [-preserve_fid] [-fid " - "FID]\n" - " [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n" - " [-f format_name] [-overwrite] [[-dsco NAME=VALUE] " - "...]\n" - " dst_datasource_name src_datasource_name\n" - " [-lco NAME=VALUE] [-nln name] [-nlt type] [layer " - "[layer ...]]\n" - "\n" - " -f format_name: output file format name, possible values are:\n"); - - for (int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++) - { - OGRSFDriver *poDriver = poR->GetDriver(iDriver); - - if (poDriver->TestCapability(ODrCCreateDataSource)) - printf(" -f \"%s\"\n", poDriver->GetName()); - } - - printf( - " -append: Append to existing layer instead of creating new if it " - "exists\n" - " -overwrite: delete the output layer and recreate it empty\n" - " -update: Open existing output datasource in update mode\n" - " -select field_list: Comma-delimited list of fields from input layer " - "to\n" - " copy to the new layer (defaults to all)\n" - " -where restricted_where: Attribute query (like SQL WHERE)\n" - " -sql statement: Execute given SQL statement and save result.\n" - " -skipfailures: skip features or layers that fail to convert\n" - " -spat xmin ymin xmax ymax: spatial query extents\n" - " -dsco NAME=VALUE: Dataset creation option (format specific)\n" - " -lco NAME=VALUE: Layer creation option (format specific)\n" - " -nln name: Assign an alternate name to the new layer\n" - " -nlt type: Force a geometry type for new layer. One of NONE, " - "GEOMETRY,\n" - " POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT, " - "MULTILINE,\n" - " MULTIPOLYGON, or MULTILINESTRING. Add \"25D\" for 3D layers.\n" - " Default is type of source layer.\n"); - - printf(" -a_srs srs_def: Assign an output SRS\n" - " -t_srs srs_def: Reproject/transform to this SRS on output\n" - " -s_srs srs_def: Override source SRS\n" - "\n" - " Srs_def can be a full WKT definition (hard to escape properly),\n" - " or a well known definition (i.e. EPSG:4326) or a file with a WKT\n" - " definition.\n"); - - exit(1); -} - -StringGeometryMap *CollectGeometries(OGRLayer *poSrcLayer, - const char **papszFields) -{ - - /* -------------------------------------------------------------------- */ - /* CollectGeometries returns a dictionary where the keys are the */ - /* values in the fields that the user has selected and the values */ - /* are a GeometryCollection of all of the geometries for records */ - /* with that value. */ - /* -------------------------------------------------------------------- */ - - StringGeometryMMap poGeometriesMap; - - poSrcLayer->ResetReading(); - - int iField; - /* -------------------------------------------------------------------- */ - /* Get all of the features and put them in a multi map. This may */ - /* include values for which the selected fields is NULL. */ - /* -------------------------------------------------------------------- */ - - for (auto &poFeature : poSrcLayer) - { - CPLString poKey(""); - - for (iField = 0; papszFields[iField] != NULL; iField++) - { - int nField = poFeature->GetFieldIndex(papszFields[iField]); - poKey = poKey + poFeature->GetFieldAsString(nField); - } - - if (poFeature->GetGeometryRef()->IsValid()) - { - poGeometriesMap.insert( - std::make_pair(CPLString(poKey), poFeature->GetGeometryRef())); - } - else - { - CPLDebug("CollectGeometries", - "Geometry was invalid not adding!!!!"); - } - } - - /* -------------------------------------------------------------------- */ - /* Loop through our features map and get a unique list of field */ - /* values. This could be done using something other than a map */ - /* of course, but it was convenient. */ - /* -------------------------------------------------------------------- */ - - typedef std::map StringIntMap; - StringIntMap::const_iterator ipos; - StringIntMap poFieldsmap; - - StringGeometryMMap::const_iterator pos; - - for (pos = poGeometriesMap.begin(); pos != poGeometriesMap.end(); ++pos) - { - - /* we currently throw out any null field values at this time */ - // if (!(pos->first.empty())) { - poFieldsmap[CPLString(pos->first.c_str())] = 1; - // } - } - - /* -------------------------------------------------------------------- */ - /* Make a new map of GeometryCollection for each value in the */ - /* poFieldsmap. This is a 1:1 relationship, and all of the */ - /* geometries for a given field are all put into the same */ - /* GeometryCollection. After we build the poCollections, we will */ - /* use GEOS' buffer(0) trick to have GEOS perform the segmentation */ - /* -------------------------------------------------------------------- */ - - StringGeometryColMap poCollections; - - CPLDebug("CollectGeometries", "Field map size: %d", poFieldsmap.size()); - - for (ipos = poFieldsmap.begin(); ipos != poFieldsmap.end(); ++ipos) - { - - CPLString fid = ipos->first; - CPLDebug("CollectGeometries", "First %s Second %d", ipos->first.c_str(), - ipos->second); - - OGRGeometryCollection *geom = new OGRGeometryCollection; - - for (pos = poGeometriesMap.lower_bound(fid); - pos != poGeometriesMap.upper_bound(fid); ++pos) - { - geom->addGeometry(pos->second); - } - poCollections.insert(std::make_pair(fid, geom)); - } - - CPLDebug("CollectGeometries", "Geo map size: %d", poCollections.size()); - - /* -------------------------------------------------------------------- */ - /* Loop through our poCollections map and buffer(0) each */ - /* GeometryCollection. GEOS will collapse the geometries down */ - /* -------------------------------------------------------------------- */ - - StringGeometryMap *buffers = new StringGeometryMap; - - StringGeometryColMap::const_iterator collections_i; - - for (collections_i = poCollections.begin(); - collections_i != poCollections.end(); ++collections_i) - { - CPLDebug("CollectGeometries", "poCollections Geometry size %d", - collections_i->second->getNumGeometries()); - OGRGeometry *buffer = collections_i->second->Buffer(0); - buffers->insert(std::make_pair(collections_i->first, buffer)); - } - - for (collections_i = poCollections.begin(); - collections_i != poCollections.end(); ++collections_i) - { - delete collections_i->second; - } - - return buffers; -} - -GeometriesList *FlattenGeometries(GeometriesList *input) -{ - - GeometriesList::const_iterator geometry_i; - GeometriesList *output = new GeometriesList; - - CPLDebug("CollectGeometries", - "Input geometries in FlattenGeometries size: %d", input->size()); - for (geometry_i = input->begin(); geometry_i != input->end(); ++geometry_i) - { - - OGRGeometry *buffer = (*geometry_i); - // int nGeometries = buffer->getNumGeometries(); - OGRwkbGeometryType iGType = buffer->getGeometryType(); - - if (iGType == wkbPolygon) - { - output->push_back(buffer); - CPLDebug("CollectGeometries", - "Collapsing wkbPolygon geometries......"); - } - if (iGType == wkbMultiPolygon) - { - OGRMultiPolygon *geom = buffer->toMultiPolygon(); - for (int i = 0; i < geom->getNumGeometries(); i++) - { - OGRPolygon *g = geom->getGeometryRef(i)->toPolygon(); - output->push_back((OGRGeometry *)g); - } - - CPLDebug("CollectGeometries", - "Collapsing wkbMultiPolygon geometries......"); - } - if (iGType == wkbGeometryCollection) - { - OGRGeometryCollection *geom = buffer->toGeometryCollection(); - GeometriesList *collection = new GeometriesList; - GeometriesList::const_iterator g_i; - for (int i = 0; i < geom->getNumGeometries(); i++) - { - OGRGeometry *g = geom->getGeometryRef(i); - collection->push_back(g); - } - GeometriesList *collapsed = FlattenGeometries(collection); - for (g_i = collapsed->begin(); g_i != collapsed->end(); g_i++) - { - output->push_back((OGRGeometry *)(*g_i)); - CPLDebug("CollectGeometries", - "Collapsing wkbGeometryCollection geometries."); - } - } - // CPLDebug( "CollectGeometries", - // "Buffered Geometry size %d", - // nGeometries); - } - - return output; -} - -/************************************************************************/ -/* DissolveLayer() */ -/************************************************************************/ - -static int DissolveLayer(OGRDataSource *poSrcDS, OGRLayer *poSrcLayer, - OGRDataSource *poDstDS, char **papszLCO, - const char *pszNewLayerName, int bTransform, - OGRSpatialReference *poOutputSRS, - OGRSpatialReference *poSourceSRS, - char **papszSelFields, int bAppend, int eGType, - int bOverwrite) - -{ - - OGRLayer *poDstLayer; - OGRFeatureDefn *poFDefn; - OGRErr eErr; - int bForceToPolygon = FALSE; - int bForceToMultiPolygon = FALSE; - - if (pszNewLayerName == NULL) - pszNewLayerName = poSrcLayer->GetLayerDefn()->GetName(); - - if (wkbFlatten(eGType) == wkbPolygon) - bForceToPolygon = TRUE; - else if (wkbFlatten(eGType) == wkbMultiPolygon) - bForceToMultiPolygon = TRUE; - - /* -------------------------------------------------------------------- */ - /* Setup coordinate transformation if we need it. */ - /* -------------------------------------------------------------------- */ - OGRCoordinateTransformation *poCT = NULL; - - if (bTransform) - { - if (poSourceSRS == NULL) - poSourceSRS = poSrcLayer->GetSpatialRef(); - - if (poSourceSRS == NULL) - { - printf("Can't transform coordinates, source layer has no\n" - "coordinate system. Use -s_srs to set one.\n"); - exit(1); - } - - CPLAssert(NULL != poSourceSRS); - CPLAssert(NULL != poOutputSRS); - - poCT = OGRCreateCoordinateTransformation(poSourceSRS, poOutputSRS); - if (poCT == NULL) - { - char *pszWKT = NULL; - - printf("Failed to create coordinate transformation between the\n" - "following coordinate systems. This may be because they\n" - "are not transformable, or because projection services\n" - "(PROJ.4 DLL/.so) could not be loaded.\n"); - - poSourceSRS->exportToPrettyWkt(&pszWKT, FALSE); - printf("Source:\n%s\n", pszWKT); - - poOutputSRS->exportToPrettyWkt(&pszWKT, FALSE); - printf("Target:\n%s\n", pszWKT); - exit(1); - } - } - - /* -------------------------------------------------------------------- */ - /* Get other info. */ - /* -------------------------------------------------------------------- */ - poFDefn = poSrcLayer->GetLayerDefn(); - - if (poOutputSRS == NULL) - poOutputSRS = poSrcLayer->GetSpatialRef(); - - /* -------------------------------------------------------------------- */ - /* Find the layer. */ - /* -------------------------------------------------------------------- */ - int iLayer = -1; - poDstLayer = NULL; - - for (iLayer = 0; iLayer < poDstDS->GetLayerCount(); iLayer++) - { - OGRLayer *poLayer = poDstDS->GetLayer(iLayer); - - if (poLayer != NULL && - EQUAL(poLayer->GetLayerDefn()->GetName(), pszNewLayerName)) - { - poDstLayer = poLayer; - break; - } - } - - /* -------------------------------------------------------------------- */ - /* If the user requested overwrite, and we have the layer in */ - /* question we need to delete it now so it will get recreated */ - /* (overwritten). */ - /* -------------------------------------------------------------------- */ - if (poDstLayer != NULL && bOverwrite) - { - if (poDstDS->DeleteLayer(iLayer) != OGRERR_NONE) - { - fprintf(stderr, "DeleteLayer() failed when overwrite requested.\n"); - return FALSE; - } - poDstLayer = NULL; - } - - /* -------------------------------------------------------------------- */ - /* If the layer does not exist, then create it. */ - /* -------------------------------------------------------------------- */ - if (poDstLayer == NULL) - { - if (eGType == -2) - eGType = poFDefn->GetGeomType(); - - if (!poDstDS->TestCapability(ODsCCreateLayer)) - { - fprintf( - stderr, - "Layer %s not found, and CreateLayer not supported by driver.", - pszNewLayerName); - return FALSE; - } - - CPLErrorReset(); - - poDstLayer = poDstDS->CreateLayer(pszNewLayerName, poOutputSRS, - (OGRwkbGeometryType)eGType, papszLCO); - - if (poDstLayer == NULL) - return FALSE; - - bAppend = FALSE; - } - - /* -------------------------------------------------------------------- */ - /* Otherwise we will append to it, if append was requested. */ - /* -------------------------------------------------------------------- */ - else if (!bAppend) - { - printf("FAILED: Layer %s already exists, and -append not specified.\n" - " Consider using -append, or -overwrite.\n", - pszNewLayerName); - return FALSE; - } - - /* -------------------------------------------------------------------- */ - /* Add fields. Default to copy all field. */ - /* If only a subset of all fields requested, then output only */ - /* the selected fields, and in the order that they were */ - /* selected. */ - /* -------------------------------------------------------------------- */ - int iField; - - if (papszSelFields && !bAppend) - { - for (iField = 0; papszSelFields[iField] != NULL; iField++) - { - int iSrcField = poFDefn->GetFieldIndex(papszSelFields[iField]); - if (iSrcField >= 0) - poDstLayer->CreateField(poFDefn->GetFieldDefn(iSrcField)); - else - { - printf("Field '%s' not found in source layer.\n", - papszSelFields[iField]); - if (!bSkipFailures) - return FALSE; - } - } - } - else if (!bAppend) - { - for (iField = 0; iField < poFDefn->GetFieldCount(); iField++) - poDstLayer->CreateField(poFDefn->GetFieldDefn(iField)); - } - - /* -------------------------------------------------------------------- */ - /* Transfer features. */ - /* -------------------------------------------------------------------- */ - OGRFeature *poFeature; - int nFeaturesInTransaction = 0; - - poSrcLayer->ResetReading(); - - if (nGroupTransactions) - poDstLayer->StartTransaction(); - - StringGeometryMap *buffers = - CollectGeometries(poSrcLayer, (const char **)papszSelFields); - - StringGeometryMap::const_iterator buffers_i; - GeometriesList *input = new GeometriesList; - - CPLDebug("CollectGeometries", "Buffers size: %d", buffers->size()); - for (buffers_i = buffers->begin(); buffers_i != buffers->end(); ++buffers_i) - { - input->push_back(buffers_i->second); - } - GeometriesList *geometries = FlattenGeometries(input); - - GeometriesList::const_iterator g_i; - for (g_i = geometries->begin(); g_i != geometries->end(); g_i++) - { - OGRFeature *feature = new OGRFeature(poFDefn); - feature->SetGeometry((*g_i)); - feature->SetField("TAXDIST", "fid"); - poDstLayer->CreateFeature(feature); - } - - if (nGroupTransactions) - poDstLayer->CommitTransaction(); - - // getGeometryType - // if( pszNewLayerName == NULL ) - // pszNewLayerName = poSrcLayer->GetLayerDefn()->GetName(); - // - // if( wkbFlatten(eGType) == wkbPolygon ) - // bForceToPolygon = TRUE; - // else if( wkbFlatten(eGType) == wkbMultiPolygon ) - // bForceToMultiPolygon = TRUE; - // - // /* -------------------------------------------------------------------- - // */ - // /* Setup coordinate transformation if we need it. */ - // /* -------------------------------------------------------------------- - // */ - // OGRCoordinateTransformation *poCT = NULL; - // - // if( bTransform ) - // { - // if( poSourceSRS == NULL ) - // poSourceSRS = poSrcLayer->GetSpatialRef(); - // - // if( poSourceSRS == NULL ) - // { - // printf( "Can't transform coordinates, source layer has no\n" - // "coordinate system. Use -s_srs to set one.\n" ); - // exit( 1 ); - // } - // - // CPLAssert( NULL != poSourceSRS ); - // CPLAssert( NULL != poOutputSRS ); - // - // poCT = OGRCreateCoordinateTransformation( poSourceSRS, - // poOutputSRS ); if( poCT == NULL ) - // { - // char *pszWKT = NULL; - // - // printf("Failed to create coordinate transformation between - // the\n" - // "following coordinate systems. This may be because - // they\n" "are not transformable, or because projection - // services\n" - // "(PROJ.4 DLL/.so) could not be loaded.\n" ); - // - // poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE ); - // printf( "Source:\n%s\n", pszWKT ); - // - // poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE ); - // printf( "Target:\n%s\n", pszWKT ); - // exit( 1 ); - // } - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* Get other info. */ - // /* -------------------------------------------------------------------- - // */ - // poFDefn = poSrcLayer->GetLayerDefn(); - // - // if( poOutputSRS == NULL ) - // poOutputSRS = poSrcLayer->GetSpatialRef(); - // - // /* -------------------------------------------------------------------- - // */ - // /* Find the layer. */ - // /* -------------------------------------------------------------------- - // */ - // int iLayer = -1; - // poDstLayer = NULL; - // - // for( iLayer = 0; iLayer < poDstDS->GetLayerCount(); iLayer++ ) - // { - // OGRLayer *poLayer = poDstDS->GetLayer(iLayer); - // - // if( poLayer != NULL - // && EQUAL(poLayer->GetLayerDefn()->GetName(),pszNewLayerName) - // ) - // { - // poDstLayer = poLayer; - // break; - // } - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* If the user requested overwrite, and we have the layer in */ - // /* question we need to delete it now so it will get recreated */ - // /* (overwritten). */ - // /* -------------------------------------------------------------------- - // */ - // if( poDstLayer != NULL && bOverwrite ) - // { - // if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE ) - // { - // fprintf( stderr, - // "DeleteLayer() failed when overwrite requested.\n" - // ); - // return FALSE; - // } - // poDstLayer = NULL; - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* If the layer does not exist, then create it. */ - // /* -------------------------------------------------------------------- - // */ - // if( poDstLayer == NULL ) - // { - // if( eGType == -2 ) - // eGType = poFDefn->GetGeomType(); - // - // if( !poDstDS->TestCapability( ODsCCreateLayer ) ) - // { - // fprintf( stderr, - // "Layer %s not found, and CreateLayer not supported by - // driver.", - // pszNewLayerName ); - // return FALSE; - // } - // - // CPLErrorReset(); - // - // poDstLayer = poDstDS->CreateLayer( pszNewLayerName, poOutputSRS, - // (OGRwkbGeometryType) eGType, - // papszLCO ); - // - // if( poDstLayer == NULL ) - // return FALSE; - // - // bAppend = FALSE; - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* Otherwise we will append to it, if append was requested. */ - // /* -------------------------------------------------------------------- - // */ - // else if( !bAppend ) - // { - // printf( "FAILED: Layer %s already exists, and -append not - // specified.\n" - // " Consider using -append, or -overwrite.\n", - // pszNewLayerName ); - // return FALSE; - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* Add fields. Default to copy all field. */ - // /* If only a subset of all fields requested, then output only */ - // /* the selected fields, and in the order that they were */ - // /* selected. */ - // /* -------------------------------------------------------------------- - // */ - // int iField; - // - // if (papszSelFields && !bAppend ) - // { - // for( iField=0; papszSelFields[iField] != NULL; iField++) - // { - // int iSrcField = - // poFDefn->GetFieldIndex(papszSelFields[iField]); if (iSrcField - // >= 0) - // poDstLayer->CreateField( poFDefn->GetFieldDefn(iSrcField) - // ); - // else - // { - // printf( "Field '%s' not found in source layer.\n", - // papszSelFields[iField] ); - // if( !bSkipFailures ) - // return FALSE; - // } - // } - // } - // else if( !bAppend ) - // { - // for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) - // poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) ); - // } - // - // /* -------------------------------------------------------------------- - // */ - // /* Transfer features. */ - // /* -------------------------------------------------------------------- - // */ - // OGRFeature *poFeature; - // int nFeaturesInTransaction = 0; - // - // poSrcLayer->ResetReading(); - // - // if( nGroupTransactions ) - // poDstLayer->StartTransaction(); - // - // while( true ) - // { - // OGRFeature *poDstFeature = NULL; - // - // if( nFIDToFetch != OGRNullFID ) - // { - // // Only fetch feature on first pass. - // if( nFeaturesInTransaction == 0 ) - // poFeature = poSrcLayer->GetFeature(nFIDToFetch); - // else - // poFeature = NULL; - // } - // else - // poFeature = poSrcLayer->GetNextFeature(); - // - // if( poFeature == NULL ) - // break; - // - // if( ++nFeaturesInTransaction == nGroupTransactions ) - // { - // poDstLayer->CommitTransaction(); - // poDstLayer->StartTransaction(); - // nFeaturesInTransaction = 0; - // } - // - // CPLErrorReset(); - // poFDefn = poSrcLayer->GetLayerDefn(); - // - // if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE ) - // { - // if( nGroupTransactions ) - // poDstLayer->CommitTransaction(); - // - // CPLError( CE_Failure, CPLE_AppDefined, - // "Unable to translate feature %d from layer %s.\n", - // poFeature->GetFID(), poFDefn->GetName() ); - // - // OGRFeature::DestroyFeature( poFeature ); - // OGRFeature::DestroyFeature( poDstFeature ); - // return FALSE; - // } - // - // if( bPreserveFID ) - // poDstFeature->SetFID( poFeature->GetFID() ); - // - // if( poCT && poDstFeature->GetGeometryRef() != NULL ) - // { - // eErr = poDstFeature->GetGeometryRef()->transform( poCT ); - // if( eErr != OGRERR_NONE ) - // { - // if( nGroupTransactions ) - // poDstLayer->CommitTransaction(); - // - // printf( "Failed to transform feature %d.\n", - // static_cast(poFeature->GetFID()) ); - // if( !bSkipFailures ) - // { - // OGRFeature::DestroyFeature( poFeature ); - // OGRFeature::DestroyFeature( poDstFeature ); - // return FALSE; - // } - // } - // } - // - // if( poDstFeature->GetGeometryRef() != NULL && bForceToPolygon ) - // { - // poDstFeature->SetGeometryDirectly( - // OGRGeometryFactory::forceToPolygon( - // poDstFeature->StealGeometry() ) ); - // } - // - // if( poDstFeature->GetGeometryRef() != NULL && - // bForceToMultiPolygon ) - // { - // poDstFeature->SetGeometryDirectly( - // OGRGeometryFactory::forceToMultiPolygon( - // poDstFeature->StealGeometry() ) ); - // } - // - // OGRFeature::DestroyFeature( poFeature ); - // - // CPLErrorReset(); - // if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE - // && !bSkipFailures ) - // { - // if( nGroupTransactions ) - // poDstLayer->RollbackTransaction(); - // - // OGRFeature::DestroyFeature( poDstFeature ); - // return FALSE; - // } - // - // OGRFeature::DestroyFeature( poDstFeature ); - // } - // - // if( nGroupTransactions ) - // poDstLayer->CommitTransaction(); - // - // /* -------------------------------------------------------------------- - // */ - // /* Cleaning */ - // /* -------------------------------------------------------------------- - // */ - // delete poCT; - - return TRUE; -} diff --git a/apps/ogrinfo_bin.cpp b/apps/ogrinfo_bin.cpp index 4bc4f08e8085..8cef461966ca 100644 --- a/apps/ogrinfo_bin.cpp +++ b/apps/ogrinfo_bin.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/ogrinfo_lib.cpp b/apps/ogrinfo_lib.cpp index b227370ddbb9..e626f7998261 100644 --- a/apps/ogrinfo_lib.cpp +++ b/apps/ogrinfo_lib.cpp @@ -8,28 +8,12 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" #include "cpl_json.h" -#include "ogrgeojsonreader.h" +#include "ogrlibjsonutils.h" #include "cpl_string.h" #include "gdal_utils.h" #include "gdal_utils_priv.h" @@ -55,7 +39,7 @@ struct GDALVectorInfoOptions GDALVectorInfoFormat eFormat = FORMAT_TEXT; std::string osWHERE{}; CPLStringList aosLayers{}; - std::unique_ptr poSpatialFilter; + std::unique_ptr poSpatialFilter{}; bool bAllLayers = false; std::string osSQLStatement{}; std::string osDialect{}; @@ -172,6 +156,7 @@ static void ReportFieldDomain(CPLString &osRet, CPLJSONObject &oDomains, osDesc.c_str()); } const char *pszType = ""; + CPL_IGNORE_RET_VAL(pszType); // Make CSA happy switch (poDomain->GetDomainType()) { case OFDT_CODED: @@ -213,6 +198,7 @@ static void ReportFieldDomain(CPLString &osRet, CPLJSONObject &oDomains, } const char *pszSplitPolicy = ""; + CPL_IGNORE_RET_VAL(pszSplitPolicy); // Make CSA happy switch (poDomain->GetSplitPolicy()) { case OFDSP_DEFAULT_VALUE: @@ -236,6 +222,7 @@ static void ReportFieldDomain(CPLString &osRet, CPLJSONObject &oDomains, } const char *pszMergePolicy = ""; + CPL_IGNORE_RET_VAL(pszMergePolicy); // Make CSA happy switch (poDomain->GetMergePolicy()) { case OFDMP_DEFAULT_VALUE: @@ -483,6 +470,7 @@ static void ReportRelationships(CPLString &osRet, CPLJSONObject &oRoot, continue; const char *pszType = ""; + CPL_IGNORE_RET_VAL(pszType); // Make CSA happy switch (poRelationship->GetType()) { case GRT_COMPOSITE: @@ -497,6 +485,7 @@ static void ReportRelationships(CPLString &osRet, CPLJSONObject &oRoot, } const char *pszCardinality = ""; + CPL_IGNORE_RET_VAL(pszCardinality); // Make CSA happy switch (poRelationship->GetCardinality()) { case GRC_ONE_TO_ONE: @@ -1841,6 +1830,10 @@ char *GDALVectorInfo(GDALDatasetH hDataset, if (poDS == nullptr) return nullptr; + const GDALVectorInfoOptions sDefaultOptions; + if (!psOptions) + psOptions = &sDefaultOptions; + GDALDriver *poDriver = poDS->GetDriver(); CPLString osRet; diff --git a/apps/ogrlineref.cpp b/apps/ogrlineref.cpp index 630eca9f4f66..206d3796d8d4 100644 --- a/apps/ogrlineref.cpp +++ b/apps/ogrlineref.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (C) 2014 NextGIS * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/ogrtindex.cpp b/apps/ogrtindex.cpp index 6a24f1e8a5e6..960fef541a68 100644 --- a/apps/ogrtindex.cpp +++ b/apps/ogrtindex.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2002, Frank Warmerdam * Copyright (c) 2007-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/apps/sozip.cpp b/apps/sozip.cpp index 1381e158ba1d..79bf539972bd 100644 --- a/apps/sozip.cpp +++ b/apps/sozip.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/apps/test_ogrsf.cpp b/apps/test_ogrsf.cpp index ddb13d4dc22b..0b4e72b6e9d4 100644 --- a/apps/test_ogrsf.cpp +++ b/apps/test_ogrsf.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2009-2014, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" @@ -1671,6 +1655,7 @@ static int TestOGRLayerFeatureCount(GDALDataset *poDS, OGRLayer *poLayer, } delete poFeat; + const auto nFCEndOfIter = LOG_ACTION(poLayer->GetFeatureCount()); if (nFC != nClaimedFC) { bRet = FALSE; @@ -1678,12 +1663,12 @@ static int TestOGRLayerFeatureCount(GDALDataset *poDS, OGRLayer *poLayer, " doesn't match actual, " CPL_FRMT_GIB ".\n", nClaimedFC, nFC); } - else if (nFC != LOG_ACTION(poLayer->GetFeatureCount())) + else if (nFC != nFCEndOfIter) { bRet = FALSE; printf("ERROR: Feature count at end of layer, " CPL_FRMT_GIB ", differs from at start, " CPL_FRMT_GIB ".\n", - poLayer->GetFeatureCount(), nFC); + nFCEndOfIter, nFC); } else if (bVerbose) printf("INFO: Feature count verified.\n"); @@ -2041,7 +2026,8 @@ static int TestOGRLayerRandomWrite(OGRLayer *poLayer) CPLString os_Id2; CPLString os_Id5; - const bool bHas_Id = poLayer->GetLayerDefn()->GetFieldIndex("_id") == 0; + const bool bHas_Id = poLayer->GetLayerDefn()->GetFieldIndex("_id") == 0 || + poLayer->GetLayerDefn()->GetFieldIndex("id") == 0; /* -------------------------------------------------------------------- */ /* Fetch five features. */ @@ -4202,8 +4188,7 @@ static int TestLayerGetArrowStream(OGRLayer *poLayer) { if (array.length != 0) { - bRet = false; - printf("ERROR: get_next() return an array with length != 0 " + printf("WARNING: get_next() return an array with length != 0 " "after end of iteration\n"); } if (array.release) diff --git a/apps/testreprojmulti.cpp b/apps/testreprojmulti.cpp index f90c80d35ad7..db1e67ec4e17 100644 --- a/apps/testreprojmulti.cpp +++ b/apps/testreprojmulti.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/autotest/alg/applyverticalshiftgrid.py b/autotest/alg/applyverticalshiftgrid.py index 8a1d36803afa..2d9cae11cc3d 100755 --- a/autotest/alg/applyverticalshiftgrid.py +++ b/autotest/alg/applyverticalshiftgrid.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/checksum.py b/autotest/alg/checksum.py index 8fc880ffba12..852f1519fda3 100644 --- a/autotest/alg/checksum.py +++ b/autotest/alg/checksum.py @@ -7,23 +7,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/alg/contour.py b/autotest/alg/contour.py index de1f67e2566a..ef0493f67284 100755 --- a/autotest/alg/contour.py +++ b/autotest/alg/contour.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct @@ -239,7 +223,7 @@ def test_contour_real_world_case(): ("1,10,20,25,30", [1, 10, 20, 25], [10, 20, 25, 30]), ("10,20,25,30", [1, 10, 20, 25], [10, 20, 25, 30]), ("10,20,24", [1, 10, 20, 24], [10, 20, 24, 25]), - ("10,20,25", [1, 10, 20], [10, 20, 25]), + ("10,20,25", [1, 10, 20, 25], [10, 20, 25, 25]), ("0,10,20", [0, 10, 20], [10, 20, 25]), ], ) @@ -290,8 +274,12 @@ def test_contour_3(input_tif, tmp_path, fixed_levels, expected_min, expected_max i = 0 for feat in lyr: - assert feat.GetField("elevMin") == expected_min[i], i - assert feat.GetField("elevMax") == expected_max[i], i + assert feat.GetField("elevMin") == pytest.approx( + expected_min[i], abs=precision / 2 * 1.001 + ), i + assert feat.GetField("elevMax") == pytest.approx( + expected_max[i], abs=precision / 2 * 1.001 + ), i envelope = feat.GetGeometryRef().GetEnvelope() for j in range(4): diff --git a/autotest/alg/cutline.py b/autotest/alg/cutline.py index de27180d5e20..7187b8964803 100755 --- a/autotest/alg/cutline.py +++ b/autotest/alg/cutline.py @@ -11,23 +11,7 @@ ############################################################################### # Copyright (c) 2008, Andrey Kiselev # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -36,6 +20,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### diff --git a/autotest/alg/data/utmsmall_lanczos_2.tif b/autotest/alg/data/utmsmall_lanczos_2.tif index fcf5c32e4c94..4d59ff20303e 100644 Binary files a/autotest/alg/data/utmsmall_lanczos_2.tif and b/autotest/alg/data/utmsmall_lanczos_2.tif differ diff --git a/autotest/alg/data/utmsmall_lanczos_50_75.tif b/autotest/alg/data/utmsmall_lanczos_50_75.tif new file mode 100644 index 000000000000..dd2444935b85 Binary files /dev/null and b/autotest/alg/data/utmsmall_lanczos_50_75.tif differ diff --git a/autotest/alg/data/utmsmall_lanczos_50_75.vrt b/autotest/alg/data/utmsmall_lanczos_50_75.vrt new file mode 100644 index 000000000000..7a6d0978f1a9 --- /dev/null +++ b/autotest/alg/data/utmsmall_lanczos_50_75.vrt @@ -0,0 +1,36 @@ + + PROJCS["NAD27 / UTM zone 11N",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213898,AUTHORITY["EPSG","7008"]],AUTHORITY["EPSG","6267"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4267"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26711"]] + 4.4072000000000000e+05, 1.2000000000000000e+02, 0.0000000000000000e+00, 3.7513200000000000e+06, 0.0000000000000000e+00, -8.0000000000000000e+01 + + Area + + + Gray + + 50 + 75 + + 6.71089e+07 + Lanczos + Byte + + + ../gcore/data/utmsmall.tif + + + 0.125 + + + 440720,60,0,3751320,0,-60 + -7345.333333333333,0.016666666666666666,0,62522,0,-0.016666666666666666 + 440720,120,0,3751320,0,-80 + -3672.6666666666665,0.0083333333333333332,0,46891.5,0,-0.012500000000000001 + + + + + + + + + diff --git a/autotest/alg/dither.py b/autotest/alg/dither.py index 6be1a702bcd0..14c960e78cf9 100755 --- a/autotest/alg/dither.py +++ b/autotest/alg/dither.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/fillnodata.py b/autotest/alg/fillnodata.py index e6830d36dec9..801469114a8f 100755 --- a/autotest/alg/fillnodata.py +++ b/autotest/alg/fillnodata.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/alg/los.py b/autotest/alg/los.py index 679b02b08cef..b4ae6ae66d08 100644 --- a/autotest/alg/los.py +++ b/autotest/alg/los.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/alg/polygonize.py b/autotest/alg/polygonize.py index 7ef5c39b0069..e0bee334af59 100755 --- a/autotest/alg/polygonize.py +++ b/autotest/alg/polygonize.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/proximity.py b/autotest/alg/proximity.py index cfb6595ec0db..a26c94e45e06 100755 --- a/autotest/alg/proximity.py +++ b/autotest/alg/proximity.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/rasterize.py b/autotest/alg/rasterize.py index 9fe6370de860..6d5a7c624cca 100755 --- a/autotest/alg/rasterize.py +++ b/autotest/alg/rasterize.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct @@ -853,6 +837,9 @@ def test_rasterize_merge_alg_add_polygon(wkt): ############################################################################### + + +@pytest.mark.require_driver("GeoJSON") def test_rasterize_bugfix_gh6981(): bad_geometry = { diff --git a/autotest/alg/reproject.py b/autotest/alg/reproject.py index 5df6b2e1b868..98527a04280d 100755 --- a/autotest/alg/reproject.py +++ b/autotest/alg/reproject.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/sieve.py b/autotest/alg/sieve.py index cf7acde9f565..069158047b28 100755 --- a/autotest/alg/sieve.py +++ b/autotest/alg/sieve.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2009-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/transformgeoloc.py b/autotest/alg/transformgeoloc.py index d4fcef36c84b..c8035ddfe16b 100755 --- a/autotest/alg/transformgeoloc.py +++ b/autotest/alg/transformgeoloc.py @@ -11,23 +11,7 @@ # Copyright (c) 2012, Frank Warmerdam # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/alg/warp.py b/autotest/alg/warp.py index fae126885e55..7d78c845a219 100755 --- a/autotest/alg/warp.py +++ b/autotest/alg/warp.py @@ -13,23 +13,7 @@ # Copyright (c) 2008, Andrey Kiselev # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -40,6 +24,11 @@ import gdaltest import pytest +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + from osgeo import gdal, osr ############################################################################### @@ -280,6 +269,17 @@ def test_warp_5_downsize(): assert maxdiff <= 1, "Image too different from reference" +def test_warp_lanczos_downsize_50_75(): + + ds = gdal.Open("data/utmsmall_lanczos_50_75.vrt") + ref_ds = gdal.Open("data/utmsmall_lanczos_50_75.tif") + maxdiff = gdaltest.compare_ds(ds, ref_ds) + ds = None + ref_ds = None + + assert maxdiff <= 1, "Image too different from reference" + + # Downsampling diff --git a/autotest/benchmark/conftest.py b/autotest/benchmark/conftest.py index 31300d39a57c..9a95f2d2ebfb 100755 --- a/autotest/benchmark/conftest.py +++ b/autotest/benchmark/conftest.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/benchmark/test_gdalwarp.py b/autotest/benchmark/test_gdalwarp.py index ba412e6c40fd..4b86fed8b1c2 100755 --- a/autotest/benchmark/test_gdalwarp.py +++ b/autotest/benchmark/test_gdalwarp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/benchmark/test_gtiff.py b/autotest/benchmark/test_gtiff.py index 920ee658bfad..7eeb1ad96d0f 100755 --- a/autotest/benchmark/test_gtiff.py +++ b/autotest/benchmark/test_gtiff.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/benchmark/test_ogr2ogr.py b/autotest/benchmark/test_ogr2ogr.py index f7f3e2af4c5e..c221855c73ca 100755 --- a/autotest/benchmark/test_ogr2ogr.py +++ b/autotest/benchmark/test_ogr2ogr.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/benchmark/test_ogr_gpkg.py b/autotest/benchmark/test_ogr_gpkg.py index fa51060b8137..8e347e245dcb 100755 --- a/autotest/benchmark/test_ogr_gpkg.py +++ b/autotest/benchmark/test_ogr_gpkg.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/conftest.py b/autotest/conftest.py index 1c962c5411ef..2e24b377f1d6 100755 --- a/autotest/conftest.py +++ b/autotest/conftest.py @@ -1,6 +1,4 @@ # coding: utf-8 -from __future__ import absolute_import, division, print_function - import os import sys diff --git a/autotest/cpp/CMakeLists.txt b/autotest/cpp/CMakeLists.txt index 74f10ca99290..e88d1910d800 100644 --- a/autotest/cpp/CMakeLists.txt +++ b/autotest/cpp/CMakeLists.txt @@ -77,7 +77,10 @@ add_executable( test_gdal_aaigrid.cpp test_gdal_dted.cpp test_gdal_gtiff.cpp + test_gdal_minmax_element.cpp test_gdal_pixelfn.cpp + test_gdal_typetraits.cpp + test_gdal_vectorx.cpp test_ogr.cpp test_ogr_organize_polygons.cpp test_ogr_geometry_stealing.cpp diff --git a/autotest/cpp/bug1488.cpp b/autotest/cpp/bug1488.cpp index ad809d23f034..704e5025dfac 100644 --- a/autotest/cpp/bug1488.cpp +++ b/autotest/cpp/bug1488.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2019, Even Rouault * Copyright (c) 2019, Thomas Bonfort * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" diff --git a/autotest/cpp/gdal_unit_test.cpp b/autotest/cpp/gdal_unit_test.cpp index 608c6fdc6ec0..08294cc0b3dd 100644 --- a/autotest/cpp/gdal_unit_test.cpp +++ b/autotest/cpp/gdal_unit_test.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifdef _MSC_VER diff --git a/autotest/cpp/gdal_unit_test.h b/autotest/cpp/gdal_unit_test.h index 5cb5eb590bf2..614249d08ca1 100644 --- a/autotest/cpp/gdal_unit_test.h +++ b/autotest/cpp/gdal_unit_test.h @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_COMMON_H_INCLUDED diff --git a/autotest/cpp/gdallimits.c b/autotest/cpp/gdallimits.c index 7d0aefbd0938..914ea2a8aa3e 100644 --- a/autotest/cpp/gdallimits.c +++ b/autotest/cpp/gdallimits.c @@ -7,23 +7,7 @@ ********************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_multiproc.h" diff --git a/autotest/cpp/googletest/CMakeLists.txt.in b/autotest/cpp/googletest/CMakeLists.txt.in index 1cdcf819370b..5055e6628fae 100644 --- a/autotest/cpp/googletest/CMakeLists.txt.in +++ b/autotest/cpp/googletest/CMakeLists.txt.in @@ -1,5 +1,5 @@ # Source https://github.com/google/googletest/blob/master/googletest/README.md -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.16) project(googletest-download NONE) @@ -10,8 +10,8 @@ endif() include(ExternalProject) ExternalProject_Add(googletest - URL https://github.com/google/googletest/archive/release-1.12.1.zip - URL_HASH SHA1=973e464e8936d4b79bb24f27b058aaef4150b06e + URL https://github.com/google/googletest/releases/download/v1.15.2/googletest-1.15.2.tar.gz + URL_HASH SHA1=568d58e26bd4e838449ca7ab8ebc152b3cbd210d DOWNLOAD_NO_PROGRESS ON SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" diff --git a/autotest/cpp/gtest_include.h b/autotest/cpp/gtest_include.h index d3088feb05f2..2ba176edbdbe 100644 --- a/autotest/cpp/gtest_include.h +++ b/autotest/cpp/gtest_include.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // Disable all warnings for gtest.h, so as to be able to still use them for diff --git a/autotest/cpp/main_gtest.cpp b/autotest/cpp/main_gtest.cpp index 24d712e24faf..2948b1d0b049 100644 --- a/autotest/cpp/main_gtest.cpp +++ b/autotest/cpp/main_gtest.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 222, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/autotest/cpp/test_alg.cpp b/autotest/cpp/test_alg.cpp index 76024d5f88c3..b3fa1706d580 100644 --- a/autotest/cpp/test_alg.cpp +++ b/autotest/cpp/test_alg.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2016, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/autotest/cpp/test_c_include_from_cpp_file.cpp b/autotest/cpp/test_c_include_from_cpp_file.cpp index 9aac400ad298..30ddf7fe408f 100644 --- a/autotest/cpp/test_c_include_from_cpp_file.cpp +++ b/autotest/cpp/test_c_include_from_cpp_file.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2017, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ extern "C" diff --git a/autotest/cpp/test_cpl.cpp b/autotest/cpp/test_cpl.cpp index be5292265689..ba43804e23b4 100644 --- a/autotest/cpp/test_cpl.cpp +++ b/autotest/cpp/test_cpl.cpp @@ -10,23 +10,7 @@ // Copyright (c) 2017, Dmitry Baryshnikov // Copyright (c) 2017, NextGIS /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_COMPILATION @@ -164,7 +148,7 @@ typedef struct // Test CPLGetValueType TEST_F(test_cpl, CPLGetValueType) { - TestStringStruct apszTestStrings[] = { + TestStringStruct asTestStrings[] = { {"+25.e+3", CPL_VALUE_REAL}, {"-25.e-3", CPL_VALUE_REAL}, {"25.e3", CPL_VALUE_REAL}, {"25e3", CPL_VALUE_REAL}, {" 25e3 ", CPL_VALUE_REAL}, {".1e3", CPL_VALUE_REAL}, @@ -177,15 +161,16 @@ TEST_F(test_cpl, CPLGetValueType) {"25.25.3", CPL_VALUE_STRING}, {"25e25e3", CPL_VALUE_STRING}, {"25e2500", CPL_VALUE_STRING}, /* #6128 */ - {"d1", CPL_VALUE_STRING} /* #6305 */ + {"d1", CPL_VALUE_STRING}, /* #6305 */ + + {"01", CPL_VALUE_STRING}, {"0.1", CPL_VALUE_REAL}, + {"0", CPL_VALUE_INTEGER}, }; - size_t i; - for (i = 0; i < sizeof(apszTestStrings) / sizeof(apszTestStrings[0]); i++) + for (const auto &sText : asTestStrings) { - EXPECT_EQ(CPLGetValueType(apszTestStrings[i].testString), - apszTestStrings[i].expectedResult) - << apszTestStrings[i].testString; + EXPECT_EQ(CPLGetValueType(sText.testString), sText.expectedResult) + << sText.testString; } } @@ -1760,6 +1745,78 @@ TEST_F(test_cpl, CPLParseRFC822DateTime) &weekday)); } +// Test CPLParseMemorySize() +TEST_F(test_cpl, CPLParseMemorySize) +{ + GIntBig nValue; + bool bUnitSpecified; + CPLErr result; + + result = CPLParseMemorySize("327mb", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, 327 * 1024 * 1024); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize("327MB", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, 327 * 1024 * 1024); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize("102.9K", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, static_cast(102.9 * 1024)); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize("102.9 kB", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, static_cast(102.9 * 1024)); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize("100%", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_GT(nValue, 100 * 1024 * 1024); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize("0", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, 0); + EXPECT_FALSE(bUnitSpecified); + + result = CPLParseMemorySize("0MB", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, 0); + EXPECT_TRUE(bUnitSpecified); + + result = CPLParseMemorySize(" 802 ", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_None); + EXPECT_EQ(nValue, 802); + EXPECT_FALSE(bUnitSpecified); + + result = CPLParseMemorySize("110%", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("8kbit", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("8ZB", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("8Z", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize(" ", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("-100MB", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); + + result = CPLParseMemorySize("nan", &nValue, &bUnitSpecified); + EXPECT_EQ(result, CE_Failure); +} + // Test CPLCopyTree() TEST_F(test_cpl, CPLCopyTree) { @@ -2846,22 +2903,23 @@ TEST_F(test_cpl, CPLJSONDocument) } // Test CPLRecodeIconv() with re-allocation +// (this test also passed on Windows using its native recoding API) TEST_F(test_cpl, CPLRecodeIconv) { -#ifdef CPL_RECODE_ICONV +#if defined(CPL_RECODE_ICONV) || defined(_WIN32) int N = 32800; char *pszIn = static_cast(CPLMalloc(N + 1)); for (int i = 0; i < N; i++) - pszIn[i] = '\xE9'; + pszIn[i] = '\xA1'; pszIn[N] = 0; char *pszExpected = static_cast(CPLMalloc(N * 2 + 1)); for (int i = 0; i < N; i++) { - pszExpected[2 * i] = '\xC3'; - pszExpected[2 * i + 1] = '\xA9'; + pszExpected[2 * i] = '\xD0'; + pszExpected[2 * i + 1] = '\x81'; } pszExpected[N * 2] = 0; - char *pszRet = CPLRecode(pszIn, "ISO-8859-2", CPL_ENC_UTF8); + char *pszRet = CPLRecode(pszIn, "ISO-8859-5", CPL_ENC_UTF8); EXPECT_EQ(memcmp(pszExpected, pszRet, N * 2 + 1), 0); CPLFree(pszIn); CPLFree(pszRet); @@ -2871,6 +2929,50 @@ TEST_F(test_cpl, CPLRecodeIconv) #endif } +// Test CP1252 to UTF-8 +TEST_F(test_cpl, CPLRecodeStubCP1252_to_UTF8_strict_alloc) +{ + CPLClearRecodeWarningFlags(); + CPLErrorReset(); + CPLPushErrorHandler(CPLQuietErrorHandler); + // Euro character expands to 3-bytes + char *pszRet = CPLRecode("\x80", "CP1252", CPL_ENC_UTF8); + CPLPopErrorHandler(); + EXPECT_STREQ(CPLGetLastErrorMsg(), ""); + EXPECT_EQ(memcmp(pszRet, "\xE2\x82\xAC\x00", 4), 0); + CPLFree(pszRet); +} + +// Test CP1252 to UTF-8 +TEST_F(test_cpl, CPLRecodeStubCP1252_to_UTF8_with_ascii) +{ + CPLClearRecodeWarningFlags(); + CPLErrorReset(); + CPLPushErrorHandler(CPLQuietErrorHandler); + char *pszRet = CPLRecode("x\x80y", "CP1252", CPL_ENC_UTF8); + CPLPopErrorHandler(); + EXPECT_STREQ(CPLGetLastErrorMsg(), ""); + EXPECT_EQ(memcmp(pszRet, "x\xE2\x82\xACy\x00", 6), 0); + CPLFree(pszRet); +} + +// Test CP1252 to UTF-8 +TEST_F(test_cpl, CPLRecodeStubCP1252_to_UTF8_with_warning) +{ + CPLClearRecodeWarningFlags(); + CPLErrorReset(); + CPLPushErrorHandler(CPLQuietErrorHandler); + // \x90 is an invalid CP1252 character. Will be skipped + char *pszRet = CPLRecode("\x90\x80", "CP1252", CPL_ENC_UTF8); + CPLPopErrorHandler(); + EXPECT_STREQ( + CPLGetLastErrorMsg(), + "One or several characters couldn't be converted correctly from CP1252 " + "to UTF-8. This warning will not be emitted anymore"); + EXPECT_EQ(memcmp(pszRet, "\xE2\x82\xAC\x00", 4), 0); + CPLFree(pszRet); +} + // Test CPLHTTPParseMultipartMime() TEST_F(test_cpl, CPLHTTPParseMultipartMime) { @@ -5286,4 +5388,194 @@ TEST_F(test_cpl, CPLSpawn) } #endif +static bool ENDS_WITH(const char *pszStr, const char *pszEnd) +{ + return strlen(pszStr) >= strlen(pszEnd) && + strcmp(pszStr + strlen(pszStr) - strlen(pszEnd), pszEnd) == 0; +} + +TEST_F(test_cpl, VSIMemGenerateHiddenFilename) +{ + { + // Initial cleanup + VSIRmdirRecursive("/vsimem/"); + VSIRmdirRecursive("/vsimem/.#!HIDDEN!#."); + + // Generate unlisted filename + const std::string osFilename1 = VSIMemGenerateHiddenFilename(nullptr); + const char *pszFilename1 = osFilename1.c_str(); + EXPECT_TRUE(STARTS_WITH(pszFilename1, "/vsimem/.#!HIDDEN!#./")); + EXPECT_TRUE(ENDS_WITH(pszFilename1, "/unnamed")); + + { + // Check the file doesn't exist yet + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(pszFilename1, &sStat), -1); + } + + // Create the file with some content + GByte abyDummyData[1] = {0}; + VSIFCloseL(VSIFileFromMemBuffer(pszFilename1, abyDummyData, + sizeof(abyDummyData), false)); + + { + // Check the file exists now + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(pszFilename1, &sStat), 0); + } + + // Gets back content + EXPECT_EQ(VSIGetMemFileBuffer(pszFilename1, nullptr, false), + abyDummyData); + + { + // Check the hidden file doesn't popup + const CPLStringList aosFiles(VSIReadDir("/vsimem/")); + EXPECT_EQ(aosFiles.size(), 0); + } + + { + // Check that we can list the below directory if we know it exists + // and there's just one subdir + const CPLStringList aosFiles(VSIReadDir("/vsimem/.#!HIDDEN!#.")); + EXPECT_EQ(aosFiles.size(), 1); + } + + { + // but that it is not an explicit directory + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL("/vsimem/.#!HIDDEN!#.", &sStat), -1); + } + + // Creates second file + const std::string osFilename2 = VSIMemGenerateHiddenFilename(nullptr); + const char *pszFilename2 = osFilename2.c_str(); + EXPECT_TRUE(strcmp(pszFilename1, pszFilename2) != 0); + + // Create it + VSIFCloseL(VSIFileFromMemBuffer(pszFilename2, abyDummyData, + sizeof(abyDummyData), false)); + + { + // Check that we can list the root hidden dir if we know it exists + const CPLStringList aosFiles(VSIReadDir("/vsimem/.#!HIDDEN!#.")); + EXPECT_EQ(aosFiles.size(), 2); + } + + { + // Create an explicit subdirectory in a hidden directory + const std::string osBaseName = + VSIMemGenerateHiddenFilename(nullptr); + const std::string osSubDir = + CPLFormFilename(osBaseName.c_str(), "mysubdir", nullptr); + EXPECT_EQ(VSIMkdir(osSubDir.c_str(), 0), 0); + + // Check the subdirectory exists + { + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(osSubDir.c_str(), &sStat), 0); + } + + // but not its hidden parent + { + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(osBaseName.c_str(), &sStat), -1); + } + + // Create file within the subdirectory + VSIFCloseL(VSIFileFromMemBuffer( + CPLFormFilename(osSubDir.c_str(), "my.bin", nullptr), + abyDummyData, sizeof(abyDummyData), false)); + + { + // Check that we can list the subdirectory + const CPLStringList aosFiles(VSIReadDir(osSubDir.c_str())); + EXPECT_EQ(aosFiles.size(), 1); + } + + { + // Check that we can list the root hidden dir if we know it exists + const CPLStringList aosFiles( + VSIReadDir("/vsimem/.#!HIDDEN!#.")); + EXPECT_EQ(aosFiles.size(), 3); + } + } + + // Directly create a directory with the return of VSIMemGenerateHiddenFilename() + { + const std::string osDirname = VSIMemGenerateHiddenFilename(nullptr); + EXPECT_EQ(VSIMkdir(osDirname.c_str(), 0), 0); + + // Check the subdirectory exists + { + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(osDirname.c_str(), &sStat), 0); + } + + // Create file within the subdirectory + VSIFCloseL(VSIFileFromMemBuffer( + CPLFormFilename(osDirname.c_str(), "my.bin", nullptr), + abyDummyData, sizeof(abyDummyData), false)); + + { + // Check there's a file in this subdirectory + const CPLStringList aosFiles(VSIReadDir(osDirname.c_str())); + EXPECT_EQ(aosFiles.size(), 1); + } + + EXPECT_EQ(VSIRmdirRecursive(osDirname.c_str()), 0); + + { + // Check there's no longer any file in this subdirectory + const CPLStringList aosFiles(VSIReadDir(osDirname.c_str())); + EXPECT_EQ(aosFiles.size(), 0); + } + + { + // Check that it no longer exists + VSIStatBufL sStat; + EXPECT_EQ(VSIStatL(osDirname.c_str(), &sStat), -1); + } + } + + // Check that operations on "/vsimem/" do not interfere with hidden files + { + // Create regular file + VSIFCloseL(VSIFileFromMemBuffer("/vsimem/regular_file", + abyDummyData, sizeof(abyDummyData), + false)); + + // Check it is visible + EXPECT_EQ(CPLStringList(VSIReadDir("/vsimem/")).size(), 1); + + // Clean root /vsimem/ + VSIRmdirRecursive("/vsimem/"); + + // No more user files + EXPECT_TRUE(CPLStringList(VSIReadDir("/vsimem/")).empty()); + + // But still hidden files + EXPECT_TRUE( + !CPLStringList(VSIReadDir("/vsimem/.#!HIDDEN!#.")).empty()); + } + + // Clean-up hidden files + EXPECT_EQ(VSIRmdirRecursive("/vsimem/.#!HIDDEN!#."), 0); + + { + // Check the root hidden dir is empty + const CPLStringList aosFiles(VSIReadDir("/vsimem/.#!HIDDEN!#.")); + EXPECT_TRUE(aosFiles.empty()); + } + + EXPECT_EQ(VSIRmdirRecursive("/vsimem/.#!HIDDEN!#."), 0); + } + + { + const std::string osFilename = VSIMemGenerateHiddenFilename("foo.bar"); + const char *pszFilename = osFilename.c_str(); + EXPECT_TRUE(STARTS_WITH(pszFilename, "/vsimem/.#!HIDDEN!#./")); + EXPECT_TRUE(ENDS_WITH(pszFilename, "/foo.bar")); + } +} } // namespace diff --git a/autotest/cpp/test_data.h b/autotest/cpp/test_data.h index 679b3553f26d..8ef6fa2cc64b 100644 --- a/autotest/cpp/test_data.h +++ b/autotest/cpp/test_data.h @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2017, Hiroshi Miura /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_TEST_DATA_H diff --git a/autotest/cpp/test_deferred_plugin.cpp b/autotest/cpp/test_deferred_plugin.cpp index 70c0a457ce36..d9f83f0be95a 100644 --- a/autotest/cpp/test_deferred_plugin.cpp +++ b/autotest/cpp/test_deferred_plugin.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_priv.h" diff --git a/autotest/cpp/test_gdal.cpp b/autotest/cpp/test_gdal.cpp index c5046797e65f..88a2e9d4a9e3 100644 --- a/autotest/cpp/test_gdal.cpp +++ b/autotest/cpp/test_gdal.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -630,6 +614,11 @@ TEST_F(test_gdal, GDALWarp_error_flush_cache) // source dataset when we want. TEST_F(test_gdal, GDALWarp_VRT) { + auto hDrv = GDALGetDriverByName("GTiff"); + if (!hDrv) + { + GTEST_SKIP() << "GTiff driver missing"; + } const char *args[] = {"-of", "VRT", nullptr}; GDALWarpAppOptions *psOptions = GDALWarpAppOptionsNew((char **)args, nullptr); @@ -646,6 +635,11 @@ TEST_F(test_gdal, GDALWarp_VRT) // source dataset when we want. TEST_F(test_gdal, GDALTranslate_VRT) { + auto hDrv = GDALGetDriverByName("GTiff"); + if (!hDrv) + { + GTEST_SKIP() << "GTiff driver missing"; + } const char *args[] = {"-of", "VRT", nullptr}; GDALTranslateOptions *psOptions = GDALTranslateOptionsNew((char **)args, nullptr); @@ -662,6 +656,11 @@ TEST_F(test_gdal, GDALTranslate_VRT) // source dataset when we want. TEST_F(test_gdal, GDALBuildVRT) { + auto hDrv = GDALGetDriverByName("GTiff"); + if (!hDrv) + { + GTEST_SKIP() << "GTiff driver missing"; + } GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly); GDALDatasetH hOutDS = GDALBuildVRT("", 1, &hSrcDS, nullptr, nullptr, nullptr); @@ -2549,6 +2548,249 @@ TEST_F(test_gdal, TileMatrixSet) } } } + + // TMS v2 with crs.uri + { + auto poTMS = gdal::TileMatrixSet::parse( + "{" + " \"id\" : \"test\"," + " \"title\" : \"test\"," + " \"uri\" : " + "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\"," + " \"crs\" : {\"uri\": " + "\"http://www.opengis.net/def/crs/EPSG/0/4326\"}," + " \"orderedAxes\" : [" + " \"Lat\"," + " \"Lon\"" + " ]," + " \"wellKnownScaleSet\" : " + "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\"," + " \"tileMatrices\" : [" + " {" + " \"id\" : \"0\"," + " \"scaleDenominator\" : 139770566.0071794390678," + " \"cellSize\" : 0.3515625," + " \"cornerOfOrigin\" : \"topLeft\"," + " \"pointOfOrigin\" : [ 90, -180 ]," + " \"matrixWidth\" : 4," + " \"matrixHeight\" : 2," + " \"tileWidth\" : 256," + " \"tileHeight\" : 256" + " }" + " ]" + "}"); + EXPECT_TRUE(poTMS != nullptr); + if (poTMS) + { + EXPECT_EQ(poTMS->crs(), + "http://www.opengis.net/def/crs/EPSG/0/4326"); + } + } + + // TMS v2 with crs.wkt + { + auto poTMS = gdal::TileMatrixSet::parse( + "{" + " \"id\" : \"test\"," + " \"title\" : \"test\"," + " \"uri\" : " + "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\"," + " \"crs\" : {\"wkt\": \"GEOGCRS[\\\"WGS 84\\\"," + "ENSEMBLE[\\\"World Geodetic System 1984 ensemble\\\"," + "MEMBER[\\\"World Geodetic System 1984 (Transit)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G730)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G873)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G1150)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G1674)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G1762)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G2139)\\\"]," + "MEMBER[\\\"World Geodetic System 1984 (G2296)\\\"]," + "ELLIPSOID[\\\"WGS 84\\\",6378137,298.257223563," + "LENGTHUNIT[\\\"metre\\\",1]]," + "ENSEMBLEACCURACY[2.0]]," + "PRIMEM[\\\"Greenwich\\\",0," + "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]]," + "CS[ellipsoidal,2]," + "AXIS[\\\"geodetic latitude (Lat)\\\",north," + "ORDER[1]," + "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]]," + "AXIS[\\\"geodetic longitude (Lon)\\\",east," + "ORDER[2]," + "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]]," + "USAGE[" + "SCOPE[\\\"Horizontal component of 3D system.\\\"]," + "AREA[\\\"World.\\\"]," + "BBOX[-90,-180,90,180]]," + "ID[\\\"EPSG\\\",4326]]\" }," + " \"orderedAxes\" : [" + " \"Lat\"," + " \"Lon\"" + " ]," + " \"wellKnownScaleSet\" : " + "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\"," + " \"tileMatrices\" : [" + " {" + " \"id\" : \"0\"," + " \"scaleDenominator\" : 139770566.0071794390678," + " \"cellSize\" : 0.3515625," + " \"cornerOfOrigin\" : \"topLeft\"," + " \"pointOfOrigin\" : [ 90, -180 ]," + " \"matrixWidth\" : 4," + " \"matrixHeight\" : 2," + " \"tileWidth\" : 256," + " \"tileHeight\" : 256" + " }" + " ]" + "}"); + EXPECT_TRUE(poTMS != nullptr); + if (poTMS) + { + EXPECT_TRUE( + STARTS_WITH(poTMS->crs().c_str(), "GEOGCRS[\"WGS 84\"")); + } + } + + // TMS v2 with crs.wkt with JSON content + { + auto poTMS = gdal::TileMatrixSet::parse( + "{" + " \"id\" : \"test\"," + " \"title\" : \"test\"," + " \"uri\" : " + "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\"," + " \"crs\" : {\"wkt\": " + "{" + " \"type\": \"GeographicCRS\"," + " \"name\": \"WGS 84\"," + " \"datum_ensemble\": {" + " \"name\": \"World Geodetic System 1984 ensemble\"," + " \"members\": [" + " {" + " \"name\": \"World Geodetic System 1984 (Transit)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1166" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G730)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1152" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G873)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1153" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G1150)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1154" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G1674)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1155" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G1762)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1156" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G2139)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1309" + " }" + " }," + " {" + " \"name\": \"World Geodetic System 1984 (G2296)\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 1383" + " }" + " }" + " ]," + " \"ellipsoid\": {" + " \"name\": \"WGS 84\"," + " \"semi_major_axis\": 6378137," + " \"inverse_flattening\": 298.257223563" + " }," + " \"accuracy\": \"2.0\"," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 6326" + " }" + " }," + " \"coordinate_system\": {" + " \"subtype\": \"ellipsoidal\"," + " \"axis\": [" + " {" + " \"name\": \"Geodetic latitude\"," + " \"abbreviation\": \"Lat\"," + " \"direction\": \"north\"," + " \"unit\": \"degree\"" + " }," + " {" + " \"name\": \"Geodetic longitude\"," + " \"abbreviation\": \"Lon\"," + " \"direction\": \"east\"," + " \"unit\": \"degree\"" + " }" + " ]" + " }," + " \"scope\": \"Horizontal component of 3D system.\"," + " \"area\": \"World.\"," + " \"bbox\": {" + " \"south_latitude\": -90," + " \"west_longitude\": -180," + " \"north_latitude\": 90," + " \"east_longitude\": 180" + " }," + " \"id\": {" + " \"authority\": \"EPSG\"," + " \"code\": 4326" + " }" + "}" + "}," + " \"orderedAxes\" : [" + " \"Lat\"," + " \"Lon\"" + " ]," + " \"wellKnownScaleSet\" : " + "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\"," + " \"tileMatrices\" : [" + " {" + " \"id\" : \"0\"," + " \"scaleDenominator\" : 139770566.0071794390678," + " \"cellSize\" : 0.3515625," + " \"cornerOfOrigin\" : \"topLeft\"," + " \"pointOfOrigin\" : [ 90, -180 ]," + " \"matrixWidth\" : 4," + " \"matrixHeight\" : 2," + " \"tileWidth\" : 256," + " \"tileHeight\" : 256" + " }" + " ]" + "}"); + EXPECT_TRUE(poTMS != nullptr); + if (poTMS) + { + EXPECT_TRUE(STARTS_WITH(poTMS->crs().c_str(), + "{ \"type\": \"GeographicCRS\"")); + } + } } // Test that PCIDSK GetMetadataItem() return is stable @@ -3004,10 +3246,15 @@ TEST_F(test_gdal, MarkSuppressOnClose) { const char *pszFilename = "/vsimem/out.tif"; const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr}; + auto hDrv = GDALGetDriverByName("GTiff"); + if (!hDrv) { - GDALDatasetUniquePtr poDstDS( - GDALDriver::FromHandle(GDALGetDriverByName("GTiff")) - ->Create(pszFilename, 1, 1, 1, GDT_Byte, apszOptions)); + GTEST_SKIP() << "GTiff driver missing"; + } + else + { + GDALDatasetUniquePtr poDstDS(GDALDriver::FromHandle(hDrv)->Create( + pszFilename, 1, 1, 1, GDT_Byte, apszOptions)); poDstDS->SetMetadataItem("FOO", "BAR"); poDstDS->MarkSuppressOnClose(); poDstDS->GetRasterBand(1)->Fill(255); @@ -3031,10 +3278,15 @@ TEST_F(test_gdal, UnMarkSuppressOnClose) { const char *pszFilename = "/vsimem/out.tif"; const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr}; + auto hDrv = GDALGetDriverByName("GTiff"); + if (!hDrv) { - GDALDatasetUniquePtr poDstDS( - GDALDriver::FromHandle(GDALGetDriverByName("GTiff")) - ->Create(pszFilename, 1, 1, 1, GDT_Byte, apszOptions)); + GTEST_SKIP() << "GTiff driver missing"; + } + else + { + GDALDatasetUniquePtr poDstDS(GDALDriver::FromHandle(hDrv)->Create( + pszFilename, 1, 1, 1, GDT_Byte, apszOptions)); poDstDS->MarkSuppressOnClose(); poDstDS->GetRasterBand(1)->Fill(255); if (poDstDS->IsMarkedSuppressOnClose()) @@ -3114,6 +3366,12 @@ TEST_F(test_gdal, GDALCachedPixelAccessor) // (https://github.com/OSGeo/gdal/issues/5989) TEST_F(test_gdal, VRTCachingOpenOptions) { + if (GDALGetMetadataItem(GDALGetDriverByName("VRT"), GDAL_DMD_OPENOPTIONLIST, + nullptr) == nullptr) + { + GTEST_SKIP() << "VRT driver Open() missing"; + } + class TestRasterBand : public GDALRasterBand { protected: @@ -3440,6 +3698,10 @@ TEST_F(test_gdal, GDALDatasetReportError) // Test GDALDataset::GetCompressionFormats() and ReadCompressedData() TEST_F(test_gdal, gtiff_ReadCompressedData) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } if (GDALGetDriverByName("JPEG") == nullptr) { GTEST_SKIP() << "JPEG support missing"; @@ -3601,6 +3863,10 @@ TEST_F(test_gdal, gtiff_ReadCompressedData) // Test GDALDataset::GetCompressionFormats() and ReadCompressedData() TEST_F(test_gdal, gtiff_ReadCompressedData_jpeg_rgba) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } if (GDALGetDriverByName("JPEG") == nullptr) { GTEST_SKIP() << "JPEG support missing"; @@ -3941,6 +4207,11 @@ TEST_F(test_gdal, jpegxl_jpeg_compatible_ReadCompressedData) // Test GDAL_OF_SHARED flag and open options TEST_F(test_gdal, open_shared_open_options) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } + CPLErrorReset(); const char *const apszOpenOptions[] = {"OVERVIEW_LEVEL=NONE", nullptr}; { @@ -4183,6 +4454,41 @@ TEST_F(test_gdal, gdal_gcp_class) } } +TEST_F(test_gdal, RasterIO_gdt_unknown) +{ + GDALDatasetUniquePtr poDS(GDALDriver::FromHandle(GDALGetDriverByName("MEM")) + ->Create("", 1, 1, 1, GDT_Float64, nullptr)); + CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler); + GByte b = 0; + GDALRasterIOExtraArg sExtraArg; + INIT_RASTERIO_EXTRA_ARG(sExtraArg); + EXPECT_EQ(poDS->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, GDT_Unknown, 1, + nullptr, 0, 0, 0, &sExtraArg), + CE_Failure); + EXPECT_EQ(poDS->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, GDT_TypeCount, 1, + nullptr, 0, 0, 0, &sExtraArg), + CE_Failure); + EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, + GDT_Unknown, 0, 0, &sExtraArg), + CE_Failure); + EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, + GDT_TypeCount, 0, 0, &sExtraArg), + CE_Failure); +} + +TEST_F(test_gdal, CopyWords_gdt_unknown) +{ + CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler); + GByte b = 0; + GByte b2 = 0; + CPLErrorReset(); + GDALCopyWords(&b, GDT_Byte, 0, &b2, GDT_Unknown, 0, 1); + EXPECT_EQ(CPLGetLastErrorType(), CE_Failure); + CPLErrorReset(); + GDALCopyWords(&b, GDT_Unknown, 0, &b2, GDT_Byte, 0, 1); + EXPECT_EQ(CPLGetLastErrorType(), CE_Failure); +} + // Test GDALRasterBand::ReadRaster TEST_F(test_gdal, ReadRaster) { @@ -4506,4 +4812,143 @@ TEST_F(test_gdal, ReadRaster) } } +// Test GDALComputeRasterMinMaxLocation +TEST_F(test_gdal, GDALComputeRasterMinMaxLocation) +{ + GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly); + ASSERT_NE(hDS, nullptr); + GDALRasterBandH hBand = GDALGetRasterBand(hDS, 1); + { + double dfMin = 0; + double dfMax = 0; + int nMinX = -1; + int nMinY = -1; + int nMaxX = -1; + int nMaxY = -1; + EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, &dfMin, &dfMax, &nMinX, + &nMinY, &nMaxX, &nMaxY), + CE_None); + EXPECT_EQ(dfMin, 74.0); + EXPECT_EQ(dfMax, 255.0); + EXPECT_EQ(nMinX, 9); + EXPECT_EQ(nMinY, 17); + EXPECT_EQ(nMaxX, 2); + EXPECT_EQ(nMaxY, 18); + GByte val = 0; + EXPECT_EQ(GDALRasterIO(hBand, GF_Read, nMinX, nMinY, 1, 1, &val, 1, 1, + GDT_Byte, 0, 0), + CE_None); + EXPECT_EQ(val, 74); + EXPECT_EQ(GDALRasterIO(hBand, GF_Read, nMaxX, nMaxY, 1, 1, &val, 1, 1, + GDT_Byte, 0, 0), + CE_None); + EXPECT_EQ(val, 255); + } + { + int nMinX = -1; + int nMinY = -1; + EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr, + &nMinX, &nMinY, nullptr, + nullptr), + CE_None); + EXPECT_EQ(nMinX, 9); + EXPECT_EQ(nMinY, 17); + } + { + int nMaxX = -1; + int nMaxY = -1; + EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr, + nullptr, nullptr, &nMaxX, + &nMaxY), + CE_None); + EXPECT_EQ(nMaxX, 2); + EXPECT_EQ(nMaxY, 18); + } + { + EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr, + nullptr, nullptr, nullptr, + nullptr), + CE_None); + } + GDALClose(hDS); +} + +// Test GDALComputeRasterMinMaxLocation +TEST_F(test_gdal, GDALComputeRasterMinMaxLocation_byte_min_max_optim) +{ + GDALDatasetUniquePtr poDS(GDALDriver::FromHandle(GDALGetDriverByName("MEM")) + ->Create("", 1, 4, 1, GDT_Byte, nullptr)); + std::array buffer = { + 1, ////////////////////////////////////////////////////////// + 0, ////////////////////////////////////////////////////////// + 255, ////////////////////////////////////////////////////////// + 1, ////////////////////////////////////////////////////////// + }; + GDALRasterIOExtraArg sExtraArg; + INIT_RASTERIO_EXTRA_ARG(sExtraArg); + EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO( + GF_Write, 0, 0, 1, 4, buffer.data(), 1, 4, GDT_Byte, + sizeof(uint8_t), 1 * sizeof(uint8_t), &sExtraArg), + CE_None); + + double dfMin = 0; + double dfMax = 0; + int nMinX = -1; + int nMinY = -1; + int nMaxX = -1; + int nMaxY = -1; + EXPECT_EQ(poDS->GetRasterBand(1)->ComputeRasterMinMaxLocation( + &dfMin, &dfMax, &nMinX, &nMinY, &nMaxX, &nMaxY), + CE_None); + EXPECT_EQ(dfMin, 0); + EXPECT_EQ(dfMax, 255); + EXPECT_EQ(nMinX, 0); + EXPECT_EQ(nMinY, 1); + EXPECT_EQ(nMaxX, 0); + EXPECT_EQ(nMaxY, 2); +} + +// Test GDALComputeRasterMinMaxLocation +TEST_F(test_gdal, GDALComputeRasterMinMaxLocation_with_mask) +{ + GDALDatasetUniquePtr poDS(GDALDriver::FromHandle(GDALGetDriverByName("MEM")) + ->Create("", 2, 2, 1, GDT_Byte, nullptr)); + std::array buffer = { + 2, 10, ////////////////////////////////////////////////////////// + 4, 20, ////////////////////////////////////////////////////////// + }; + GDALRasterIOExtraArg sExtraArg; + INIT_RASTERIO_EXTRA_ARG(sExtraArg); + EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO( + GF_Write, 0, 0, 2, 2, buffer.data(), 2, 2, GDT_Byte, + sizeof(uint8_t), 2 * sizeof(uint8_t), &sExtraArg), + CE_None); + + poDS->GetRasterBand(1)->CreateMaskBand(0); + std::array buffer_mask = { + 0, 255, ////////////////////////////////////////////////////////// + 255, 0, ////////////////////////////////////////////////////////// + }; + EXPECT_EQ(poDS->GetRasterBand(1)->GetMaskBand()->RasterIO( + GF_Write, 0, 0, 2, 2, buffer_mask.data(), 2, 2, GDT_Byte, + sizeof(uint8_t), 2 * sizeof(uint8_t), &sExtraArg), + CE_None); + + double dfMin = 0; + double dfMax = 0; + int nMinX = -1; + int nMinY = -1; + int nMaxX = -1; + int nMaxY = -1; + EXPECT_EQ(poDS->GetRasterBand(1)->ComputeRasterMinMaxLocation( + &dfMin, &dfMax, &nMinX, &nMinY, &nMaxX, &nMaxY), + CE_None); + EXPECT_EQ(dfMin, 4); + EXPECT_EQ(dfMax, 10); + EXPECT_EQ(nMinX, 0); + EXPECT_EQ(nMinY, 1); + EXPECT_EQ(nMaxX, 1); + EXPECT_EQ(nMaxY, 0); +} + } // namespace diff --git a/autotest/cpp/test_gdal_aaigrid.cpp b/autotest/cpp/test_gdal_aaigrid.cpp index 55833bd929c1..72903bea1e2e 100644 --- a/autotest/cpp/test_gdal_aaigrid.cpp +++ b/autotest/cpp/test_gdal_aaigrid.cpp @@ -8,23 +8,7 @@ // Copyright (c) 2006, Mateusz Loskot // Copyright (c) 2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -219,6 +203,11 @@ TEST_F(test_gdal_aaigrid, nodata) // Create simple copy and check TEST_F(test_gdal_aaigrid, copy) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } + // Index of test file being tested const std::size_t fileIdx = 0; diff --git a/autotest/cpp/test_gdal_dted.cpp b/autotest/cpp/test_gdal_dted.cpp index 7af3b3032fc2..7622aca2e921 100644 --- a/autotest/cpp/test_gdal_dted.cpp +++ b/autotest/cpp/test_gdal_dted.cpp @@ -8,23 +8,7 @@ // Copyright (c) 2006, Mateusz Loskot // Copyright (c) 2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_gdal_gtiff.cpp b/autotest/cpp/test_gdal_gtiff.cpp index b9a24c5a59b3..daeb847622b1 100644 --- a/autotest/cpp/test_gdal_gtiff.cpp +++ b/autotest/cpp/test_gdal_gtiff.cpp @@ -8,23 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_gdal_minmax_element.cpp b/autotest/cpp/test_gdal_minmax_element.cpp new file mode 100644 index 000000000000..b6d681dda76d --- /dev/null +++ b/autotest/cpp/test_gdal_minmax_element.cpp @@ -0,0 +1,900 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Project: C++ Test Suite for GDAL/OGR +// Purpose: Test gdal_minmax_element.hpp +// Author: Even Rouault +// +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2023, Even Rouault +/* + * SPDX-License-Identifier: MIT + ****************************************************************************/ + +#include "gdal_unit_test.h" + +#include "gdal_minmax_element.hpp" + +#include "gtest_include.h" + +#include + +namespace +{ + +struct test_gdal_minmax_element : public ::testing::Test +{ +}; + +TEST_F(test_gdal_minmax_element, uint8) +{ + using T = uint8_t; + constexpr GDALDataType eDT = GDT_Byte; + T min_v = 3; + T max_v = 7; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), + static_cast(max_v - 1), + max_v, + static_cast(max_v - 1), + static_cast(min_v + 1), + min_v, + static_cast(min_v + 1)}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[125] = static_cast(min_v + 1); + v[126] = min_v; + v[127] = static_cast(min_v + 1); + v[128] = static_cast(max_v - 1); + v[129] = max_v; + v[130] = static_cast(max_v - 1); + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } + { + std::vector v(257, 0); + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, 0); + EXPECT_TRUE(idx_min == 0 || idx_min == 256) << idx_min; + } + { + std::vector v(257, 0); + v[127] = static_cast(min_v + 1); + v[255] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, 0); + EXPECT_EQ(v[idx_min], min_v); + } + { + std::vector v(259, static_cast((min_v + max_v) / 2)); + v[0] = min_v; + v[256] = static_cast(max_v - 1); + v[257] = max_v; + v[258] = static_cast(max_v - 1); + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[0] = min_v; + v[127] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[127] = min_v; + v[0] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[0] = min_v; + v[129] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[129] = min_v; + v[0] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[129] = min_v; + v[256] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[256] = min_v; + v[129] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, 0); + v[65] = static_cast(max_v - 2); + v[66] = static_cast(max_v - 1); + v[129] = max_v; + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, 0); + EXPECT_EQ(v[idx_max], max_v); + } +} + +TEST_F(test_gdal_minmax_element, int8) +{ + using T = int8_t; + T min_v = -1; + T max_v = 3; + constexpr GDALDataType eDT = GDT_Int8; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, uint16) +{ + using T = uint16_t; + constexpr GDALDataType eDT = GDT_UInt16; + T min_v = 1000; + T max_v = 2000; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, int16) +{ + using T = int16_t; + constexpr GDALDataType eDT = GDT_Int16; + T min_v = -1000; + T max_v = 2000; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, uint32) +{ + using T = uint32_t; + constexpr GDALDataType eDT = GDT_UInt32; + T min_v = 10000000; + T max_v = 20000000; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, int32) +{ + using T = int32_t; + constexpr GDALDataType eDT = GDT_Int32; + T min_v = -10000000; + T max_v = 20000000; + { + T nodata = 0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, uint64) +{ + using T = uint64_t; + constexpr GDALDataType eDT = GDT_UInt64; + T min_v = 100000000000000; + T max_v = 200000000000000; + { + double nodata = 0; + std::vector v{max_v, static_cast(nodata), min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + double nodata = 0; + std::vector v{static_cast(nodata), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(static_cast(min_v + 1))); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, int64) +{ + using T = int64_t; + constexpr GDALDataType eDT = GDT_Int64; + T min_v = -100000000000000; + T max_v = 200000000000000; + { + double nodata = 0; + std::vector v{max_v, static_cast(nodata), min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + double nodata = 0; + std::vector v{static_cast(nodata), max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{static_cast((min_v + max_v) / 2), + max_v - 1, + max_v, + max_v - 1, + min_v + 1, + min_v, + min_v + 1}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast((min_v + max_v) / 2)); + v[5] = min_v; + v[31] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 2)); + v[128] = static_cast(min_v + 1); + v[256] = min_v; + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(static_cast(min_v + 1))); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, float32) +{ + using T = float; + constexpr GDALDataType eDT = GDT_Float32; + T min_v = 1.0f; + T max_v = 1.5f; + { + T nodata = 2.0f; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 2.0f; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + T nodata = 2.0f; + std::vector v{std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), nodata, max_v, + min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + T nodata = std::numeric_limits::quiet_NaN(); + std::vector v{std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), nodata, max_v, + min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + max_v, + std::numeric_limits::quiet_NaN(), + min_v, + std::numeric_limits::quiet_NaN()}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{max_v, std::numeric_limits::quiet_NaN(), min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, std::numeric_limits::quiet_NaN()); + v[125] = static_cast(min_v + 0.1f); + v[126] = min_v; + v[127] = static_cast(min_v + 0.1f); + v[128] = static_cast(max_v - 0.1f); + v[129] = max_v; + v[130] = static_cast(max_v - 0.1f); + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(33, 1.2f); + v[5] = min_v; + v[15] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(255, std::numeric_limits::quiet_NaN()); + v[v.size() - 2] = min_v; + v.back() = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 0.2f)); + v[128] = static_cast(min_v + 0.1f); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 0.1f)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, float64) +{ + using T = double; + constexpr GDALDataType eDT = GDT_Float64; + T min_v = 1.0; + T max_v = 1.5; + { + T nodata = 2.0; + std::vector v{max_v, nodata, min_v}; + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, true, nodata); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = gdal::min_element(v.data(), 0, eDT, false, 0); + EXPECT_EQ(idx_min, 0); + } + { + auto idx_min = + gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = + gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + auto [idx_min, idx_max] = + gdal::minmax_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + EXPECT_EQ(v[idx_max], max_v); + } + } + { + T nodata = 2.0; + std::vector v{nodata, max_v, min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + T nodata = 2.0; + std::vector v{std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), nodata, max_v, + min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, true, nodata); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{max_v, std::numeric_limits::quiet_NaN(), min_v}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v{std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + max_v, + std::numeric_limits::quiet_NaN(), + min_v, + std::numeric_limits::quiet_NaN()}; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(33, std::numeric_limits::quiet_NaN()); + v[5] = min_v; + v[15] = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(255, std::numeric_limits::quiet_NaN()); + v[v.size() - 2] = min_v; + v.back() = max_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_min], min_v); + auto idx_max = gdal::max_element(v.data(), v.size(), eDT, false, 0); + EXPECT_EQ(v[idx_max], max_v); + } + { + std::vector v(257, static_cast(min_v + 0.2)); + v[128] = static_cast(min_v + 0.1); + v[256] = min_v; + auto idx_min = gdal::min_element(v.data(), v.size(), eDT, true, + static_cast(min_v + 0.1)); + EXPECT_EQ(v[idx_min], min_v); + } +} + +TEST_F(test_gdal_minmax_element, unsupported) +{ + float v[2] = {0, 0}; + CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler); + { + CPLErrorReset(); + EXPECT_EQ(gdal::min_element(v, 1, GDT_CFloat32, false, 0), 0); + EXPECT_EQ(CPLGetLastErrorNo(), CPLE_NotSupported); + } + { + CPLErrorReset(); + EXPECT_EQ(gdal::max_element(v, 1, GDT_CFloat32, false, 0), 0); + EXPECT_EQ(CPLGetLastErrorNo(), CPLE_NotSupported); + } + { + CPLErrorReset(); + auto [idx_min, idx_max] = + gdal::minmax_element(v, 1, GDT_CFloat32, false, 0); + EXPECT_EQ(idx_min, 0); + EXPECT_EQ(idx_max, 0); + EXPECT_EQ(CPLGetLastErrorNo(), CPLE_NotSupported); + } +} + +} // namespace diff --git a/autotest/cpp/test_gdal_pixelfn.cpp b/autotest/cpp/test_gdal_pixelfn.cpp index 6adfbc567636..ae3a6707193d 100644 --- a/autotest/cpp/test_gdal_pixelfn.cpp +++ b/autotest/cpp/test_gdal_pixelfn.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2022, Momtchil Momtchev /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -170,11 +154,25 @@ struct test_gdal_pixelfn : public ::testing::Test src_ += SEP; src_ += "pixelfn.vrt"; } + + void SetUp() override + { + if (GDALGetMetadataItem(GDALGetDriverByName("VRT"), + GDAL_DMD_OPENOPTIONLIST, nullptr) == nullptr) + { + GTEST_SKIP() << "VRT driver Open() missing"; + } + } }; // Test constant parameters in a custom pixel function TEST_F(test_gdal_pixelfn, custom_pixel_fn_constant_parameters) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } + GDALAddDerivedBandPixelFuncWithArgs("custom", CustomPixelFuncWithMetadata, pszFuncMetadata); GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly); @@ -195,6 +193,11 @@ TEST_F(test_gdal_pixelfn, custom_pixel_fn_constant_parameters) // Test registering of a custom pixel function without metadata TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_metadata) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } + GDALAddDerivedBandPixelFuncWithArgs("custom2", CustomPixelFunc, nullptr); GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly); ASSERT_TRUE(nullptr != ds); @@ -218,6 +221,11 @@ TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_metadata) // Test the registering of a custom pixel function without args TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_args) { + if (!GDALGetDriverByName("GTiff")) + { + GTEST_SKIP() << "GTiff driver missing"; + } + GDALAddDerivedBandPixelFunc("custom3", CustomPixelFuncNoArgs); GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly); ASSERT_TRUE(nullptr != ds); diff --git a/autotest/cpp/test_gdal_typetraits.cpp b/autotest/cpp/test_gdal_typetraits.cpp new file mode 100644 index 000000000000..90bc1e24566b --- /dev/null +++ b/autotest/cpp/test_gdal_typetraits.cpp @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: MIT +// Copyright 2024, Even Rouault + +#include "gdal_unit_test.h" + +#include "gdal_typetraits.h" + +#include "gtest_include.h" + +namespace +{ + +struct test_gdal_typetraits : public ::testing::Test +{ +}; + +TEST_F(test_gdal_typetraits, CXXTypeTraits) +{ + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Int8); + static_assert(gdal::CXXTypeTraits::size == 1); + EXPECT_EQ( + gdal::CXXTypeTraits::GetExtendedDataType().GetNumericDataType(), + GDT_Int8); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Byte); + static_assert(gdal::CXXTypeTraits::size == 1); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Byte); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Int16); + static_assert(gdal::CXXTypeTraits::size == 2); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int16); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_UInt16); + static_assert(gdal::CXXTypeTraits::size == 2); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt16); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Int32); + static_assert(gdal::CXXTypeTraits::size == 4); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int32); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_UInt32); + static_assert(gdal::CXXTypeTraits::size == 4); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt32); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Int64); + static_assert(gdal::CXXTypeTraits::size == 8); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int64); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_UInt64); + static_assert(gdal::CXXTypeTraits::size == 8); + EXPECT_EQ(gdal::CXXTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt64); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Float32); + static_assert(gdal::CXXTypeTraits::size == 4); + EXPECT_EQ( + gdal::CXXTypeTraits::GetExtendedDataType().GetNumericDataType(), + GDT_Float32); + static_assert(gdal::CXXTypeTraits::gdal_type == GDT_Float64); + static_assert(gdal::CXXTypeTraits::size == 8); + EXPECT_EQ( + gdal::CXXTypeTraits::GetExtendedDataType().GetNumericDataType(), + GDT_Float64); + static_assert(gdal::CXXTypeTraits>::gdal_type == + GDT_CFloat32); + static_assert(gdal::CXXTypeTraits>::size == 8); + EXPECT_EQ(gdal::CXXTypeTraits>::GetExtendedDataType() + .GetNumericDataType(), + GDT_CFloat32); + static_assert(gdal::CXXTypeTraits>::gdal_type == + GDT_CFloat64); + static_assert(gdal::CXXTypeTraits>::size == 16); + EXPECT_EQ(gdal::CXXTypeTraits>::GetExtendedDataType() + .GetNumericDataType(), + GDT_CFloat64); + static_assert(gdal::CXXTypeTraits::size == 0); + EXPECT_EQ( + gdal::CXXTypeTraits::GetExtendedDataType().GetClass(), + GEDTC_STRING); +} + +TEST_F(test_gdal_typetraits, GDALDataTypeTraits) +{ + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Byte); + static_assert( + std::is_same_v::type, uint8_t>); + static_assert(gdal::GDALDataTypeTraits::size == 1); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int8); + static_assert( + std::is_same_v::type, int8_t>); + static_assert(gdal::GDALDataTypeTraits::size == 1); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int16); + static_assert( + std::is_same_v::type, int16_t>); + static_assert(gdal::GDALDataTypeTraits::size == 2); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt16); + static_assert( + std::is_same_v::type, uint16_t>); + static_assert(gdal::GDALDataTypeTraits::size == 2); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int32); + static_assert( + std::is_same_v::type, int32_t>); + static_assert(gdal::GDALDataTypeTraits::size == 4); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt32); + static_assert( + std::is_same_v::type, uint32_t>); + static_assert(gdal::GDALDataTypeTraits::size == 4); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Int64); + static_assert( + std::is_same_v::type, int64_t>); + static_assert(gdal::GDALDataTypeTraits::size == 8); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_UInt64); + static_assert( + std::is_same_v::type, uint64_t>); + static_assert(gdal::GDALDataTypeTraits::size == 8); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Float32); + static_assert( + std::is_same_v::type, float>); + static_assert(gdal::GDALDataTypeTraits::size == 4); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_Float64); + static_assert( + std::is_same_v::type, double>); + static_assert(gdal::GDALDataTypeTraits::size == 8); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_CInt16); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_CInt32); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_CFloat32); + static_assert(std::is_same_v::type, + std::complex>); + static_assert(gdal::GDALDataTypeTraits::size == 8); + EXPECT_EQ(gdal::GDALDataTypeTraits::GetExtendedDataType() + .GetNumericDataType(), + GDT_CFloat64); + static_assert(std::is_same_v::type, + std::complex>); + static_assert(gdal::GDALDataTypeTraits::size == 16); +} + +TEST_F(test_gdal_typetraits, GetOGRFieldType) +{ + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Byte), OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Int8), OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Int16), OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Int32), OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_UInt16), OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_UInt32), OFTInteger64); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Int64), OFTInteger64); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_UInt64), OFTReal); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Float32), OFTReal); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Float64), OFTReal); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_CInt16), OFTMaxType); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_CInt32), OFTMaxType); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_CFloat32), OFTMaxType); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_CFloat64), OFTMaxType); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_Unknown), OFTMaxType); + EXPECT_EQ(gdal::GetOGRFieldType(GDT_TypeCount), OFTMaxType); + + EXPECT_EQ(gdal::GetOGRFieldType(GDALExtendedDataType::Create(GDT_Byte)), + OFTInteger); + EXPECT_EQ(gdal::GetOGRFieldType(GDALExtendedDataType::CreateString()), + OFTString); + EXPECT_EQ( + gdal::GetOGRFieldType(GDALExtendedDataType::Create("compound", 0, {})), + OFTMaxType); +} + +} // namespace diff --git a/autotest/cpp/test_gdal_vectorx.cpp b/autotest/cpp/test_gdal_vectorx.cpp new file mode 100644 index 000000000000..94bb2e6c3514 --- /dev/null +++ b/autotest/cpp/test_gdal_vectorx.cpp @@ -0,0 +1,337 @@ +/****************************************************************************** + * Project: GDAL Vector abstraction + * Purpose: Tests for the VectorX class + * Author: Javier Jimenez Shaw + * + ****************************************************************************** + * Copyright (c) 2024, Javier Jimenez Shaw + * + * SPDX-License-Identifier: MIT + ****************************************************************************/ + +#include "gdal_unit_test.h" + +#include "gdal_vectorx.h" + +#include +#include +#include +#include + +#include "gtest_include.h" + +namespace +{ + +// Common fixture with test data +struct test_vectorx : public ::testing::Test +{ +}; + +// Dummy test +TEST_F(test_vectorx, simple_int) +{ + gdal::Vector2i a; + EXPECT_EQ(0, a.x()); + EXPECT_EQ(0, a.y()); + static_assert(std::is_same_v == true); + + gdal::Vector2i p2(2, 3); + EXPECT_EQ(2, p2.x()); + EXPECT_EQ(3, p2.y()); + + gdal::Vector3i p3(12, 13, 14); + EXPECT_EQ(12, p3.x()); + EXPECT_EQ(13, p3.y()); + EXPECT_EQ(14, p3.z()); + + gdal::VectorX p1{2}; + EXPECT_EQ(2, p1.x()); + + gdal::VectorX p4(12, 13, -14, 150); + EXPECT_EQ(12, p4.x()); + EXPECT_EQ(13, p4.y()); + EXPECT_EQ(-14, p4.z()); + EXPECT_EQ(150, p4[3]); +} + +TEST_F(test_vectorx, simple_double) +{ + gdal::Vector2d a; + EXPECT_EQ(0.0, a.x()); + EXPECT_EQ(0.0, a.y()); + EXPECT_EQ(2, a.size()); + static_assert(std::is_same_v == true); + + gdal::Vector2d p2(2.1, 3.6); + EXPECT_EQ(2.1, p2.x()); + EXPECT_EQ(3.6, p2.y()); + EXPECT_EQ(2, p2.size()); + + gdal::Vector3d p3(12e-2, -13.0, 14e3); + EXPECT_EQ(12e-2, p3.x()); + EXPECT_EQ(-13.0, p3.y()); + EXPECT_EQ(14e3, p3.z()); + EXPECT_EQ(3, p3.size()); + + gdal::VectorX p1{2.1}; + EXPECT_EQ(2.1, p1.x()); + EXPECT_EQ(1, p1.size()); + + gdal::VectorX p4(12.0, 13.1, -14.2, 150.0); + EXPECT_EQ(12.0, p4.x()); + EXPECT_EQ(13.1, p4.y()); + EXPECT_EQ(-14.2, p4.z()); + EXPECT_EQ(150.0, p4[3]); + EXPECT_EQ(4, p4.size()); +} + +TEST_F(test_vectorx, simple_float) +{ + gdal::VectorX p1{2.1f}; + EXPECT_EQ(2.1f, p1.x()); + static_assert(std::is_same_v == true); + + gdal::VectorX p4(12.0f, 13.1f, -14.2f, 150.0f); + EXPECT_EQ(12.0f, p4.x()); + EXPECT_EQ(13.1f, p4.y()); + EXPECT_EQ(-14.2f, p4.z()); + EXPECT_EQ(150.0f, p4[3]); +} + +TEST_F(test_vectorx, simple_complex) +{ + using namespace std::complex_literals; + gdal::VectorX, 2> p2{2.1 + 3.0i, -9.0 + -7.0i}; + EXPECT_EQ(2.1 + 3.0i, p2.x()); + EXPECT_EQ(-9.0 + -7.0i, p2.y()); + static_assert( + std::is_same_v> == true); +} + +TEST_F(test_vectorx, array) +{ + gdal::Vector2d p2(2.1, 3.6); + const std::array arr = p2.array(); + EXPECT_EQ(2.1, arr[0]); + EXPECT_EQ(3.6, arr[1]); +} + +TEST_F(test_vectorx, fill) +{ + const gdal::Vector3d a = gdal::Vector3d().fill(42.0); + EXPECT_EQ(3, a.size()); + EXPECT_EQ(42.0, a[0]); + EXPECT_EQ(42.0, a[1]); + EXPECT_EQ(42.0, a[2]); +} + +TEST_F(test_vectorx, fill_nan) +{ + const gdal::Vector3d a = + gdal::Vector3d().fill(std::numeric_limits::quiet_NaN()); + EXPECT_EQ(3, a.size()); + EXPECT_TRUE(std::isnan(a[0])); + EXPECT_TRUE(std::isnan(a[1])); + EXPECT_TRUE(std::isnan(a[2])); +} + +TEST_F(test_vectorx, change) +{ + gdal::Vector2d p2(2.1, 3.6); + p2[0] = 7; + EXPECT_EQ(7, p2.x()); + p2[1] = 10.5; + EXPECT_EQ(10.5, p2.y()); + + gdal::Vector3d p3(12.1, 13.6, -9.0); + p3.x() = 79; + EXPECT_EQ(79, p3[0]); + p3.y() = 10.4; + EXPECT_EQ(10.4, p3[1]); + p3.z() = 1.5; + EXPECT_EQ(1.5, p3[2]); +} + +TEST_F(test_vectorx, scalar_prod) +{ + gdal::Vector2d a(2.1, 3.6); + gdal::Vector2d b(-2.0, 10.0); + EXPECT_NEAR(2.1 * -2.0 + 3.6 * 10.0, a.scalarProd(b), 1e-10); +} + +TEST_F(test_vectorx, norm2) +{ + gdal::Vector2d a(2.1, 3.6); + EXPECT_NEAR(2.1 * 2.1 + 3.6 * 3.6, a.norm2(), 1e-10); +} + +TEST_F(test_vectorx, cast) +{ + gdal::Vector2d a(2.1, -3.6); + auto b = a.cast(); + static_assert(std::is_same_v == true); + EXPECT_EQ(2, b.x()); + EXPECT_EQ(-3, b.y()); + + gdal::Vector2d c = b.cast(); + static_assert(std::is_same_v == true); + EXPECT_EQ(2.0, c.x()); + EXPECT_EQ(-3.0, c.y()); +} + +TEST_F(test_vectorx, floor) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d d = a.floor(); + EXPECT_EQ(2.0, d.x()); + EXPECT_EQ(-4.0, d.y()); + + // just to show how to use the template keyword. + const gdal::Vector2i i = a.floor().template cast(); + EXPECT_EQ(2, i.x()); + EXPECT_EQ(-4, i.y()); +} + +TEST_F(test_vectorx, ceil) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d d = a.ceil(); + EXPECT_EQ(3.0, d.x()); + EXPECT_EQ(-3.0, d.y()); +} + +TEST_F(test_vectorx, apply) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d d = + a.apply([](const gdal::Vector2d::value_type v) { return v + 1.0; }); + EXPECT_NEAR(3.1, d.x(), 1e-10); + EXPECT_NEAR(-2.6, d.y(), 1e-10); +} + +TEST_F(test_vectorx, sum) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d b = a + 2.2; + EXPECT_NEAR(4.3, b.x(), 1e-10); + EXPECT_NEAR(-1.4, b.y(), 1e-10); +} + +TEST_F(test_vectorx, sum_eq) +{ + gdal::Vector2d a(2.1, -3.6); + a += 2.0; + EXPECT_NEAR(4.1, a.x(), 1e-10); + EXPECT_NEAR(-1.6, a.y(), 1e-10); +} + +TEST_F(test_vectorx, sum_eq_int) +{ + gdal::Vector2i a(2, -3); + a += 1; + EXPECT_EQ(3, a.x()); + EXPECT_EQ(-2, a.y()); +} + +TEST_F(test_vectorx, minus) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d b = a - 2.2; + EXPECT_NEAR(-0.1, b.x(), 1e-10); + EXPECT_NEAR(-5.8, b.y(), 1e-10); +} + +TEST_F(test_vectorx, minus_eq) +{ + gdal::Vector2d a(2.1, -3.6); + a -= 2.0; + EXPECT_NEAR(0.1, a.x(), 1e-10); + EXPECT_NEAR(-5.6, a.y(), 1e-10); +} + +TEST_F(test_vectorx, minus_eq_int) +{ + gdal::Vector2i a(2, -3); + a -= 1; + EXPECT_EQ(1, a.x()); + EXPECT_EQ(-4, a.y()); +} + +TEST_F(test_vectorx, minus_op) +{ + gdal::Vector2d a(2.1, -3.6); + const auto b = -a; + EXPECT_NEAR(-2.1, b.x(), 1e-10); + EXPECT_NEAR(3.6, b.y(), 1e-10); +} + +TEST_F(test_vectorx, multiply_int_double) +{ + gdal::Vector2i a(2, -3); + const auto b = a * 2.6; + static_assert(std::is_same_v == true); + EXPECT_EQ(5, b.x()); + EXPECT_EQ(-7, b.y()); +} + +TEST_F(test_vectorx, multiply_double) +{ + gdal::Vector2d a(2.1, -3.2); + const auto b = a * 2.6; + EXPECT_NEAR(5.46, b.x(), 1e-10); + EXPECT_NEAR(-8.32, b.y(), 1e-10); +} + +TEST_F(test_vectorx, divide_int_double) +{ + gdal::Vector2i a(4, -3); + const auto b = a / 2.2; + static_assert(std::is_same_v == true); + EXPECT_EQ(1, b.x()); + EXPECT_EQ(-1, b.y()); +} + +TEST_F(test_vectorx, divide_double) +{ + gdal::Vector2d a(2.1, -3.2); + const auto b = a / 2.5; + EXPECT_NEAR(0.84, b.x(), 1e-10); + EXPECT_NEAR(-1.28, b.y(), 1e-10); +} + +TEST_F(test_vectorx, plus_vectorx) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d b(10.0, 1.1); + const auto c = a + b; + EXPECT_NEAR(12.1, c.x(), 1e-10); + EXPECT_NEAR(-2.5, c.y(), 1e-10); +} + +TEST_F(test_vectorx, minus_vectorx) +{ + const gdal::Vector2d a(2.1, -3.6); + const gdal::Vector2d b(10.0, 1.1); + const auto c = a - b; + EXPECT_NEAR(-7.9, c.x(), 1e-10); + EXPECT_NEAR(-4.7, c.y(), 1e-10); +} + +TEST_F(test_vectorx, plus_scalar_vectorx) +{ + const gdal::Vector2d a(2.1, -3.6); + const auto b = 2.5 + a; + EXPECT_NEAR(4.6, b.x(), 1e-10); + EXPECT_NEAR(-1.1, b.y(), 1e-10); +} + +TEST_F(test_vectorx, minus_scalar_vectorx) +{ + const gdal::Vector2d a(2.1, -3.6); + const auto b = 2.5 - a; + EXPECT_NEAR(0.4, b.x(), 1e-10); + EXPECT_NEAR(6.1, b.y(), 1e-10); +} + +} // namespace diff --git a/autotest/cpp/test_include_from_c_file.c b/autotest/cpp/test_include_from_c_file.c index 869a2b506a8c..60ae47479a37 100644 --- a/autotest/cpp/test_include_from_c_file.c +++ b/autotest/cpp/test_include_from_c_file.c @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2017, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // PLEASE DO NOT RENAME THIS FILE AS .cpp !!!!! diff --git a/autotest/cpp/test_marching_squares_contour.cpp b/autotest/cpp/test_marching_squares_contour.cpp index aea8a210979d..47718ed67787 100644 --- a/autotest/cpp/test_marching_squares_contour.cpp +++ b/autotest/cpp/test_marching_squares_contour.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2018, Hugo Mercier, * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_marching_squares_polygon.cpp b/autotest/cpp/test_marching_squares_polygon.cpp index d2d3fff8da5c..3b1edf6d36cf 100644 --- a/autotest/cpp/test_marching_squares_polygon.cpp +++ b/autotest/cpp/test_marching_squares_polygon.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2018, Hugo Mercier, * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_marching_squares_square.cpp b/autotest/cpp/test_marching_squares_square.cpp index bab7d6131434..c1ffec9eef72 100644 --- a/autotest/cpp/test_marching_squares_square.cpp +++ b/autotest/cpp/test_marching_squares_square.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2018, Hugo Mercier, * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_marching_squares_tile.cpp b/autotest/cpp/test_marching_squares_tile.cpp index ac3b0adaddc8..3151593e20c7 100644 --- a/autotest/cpp/test_marching_squares_tile.cpp +++ b/autotest/cpp/test_marching_squares_tile.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2018, Hugo Mercier, * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_ogr.cpp b/autotest/cpp/test_ogr.cpp index e75d0b6253b9..8a91c026f57b 100644 --- a/autotest/cpp/test_ogr.cpp +++ b/autotest/cpp/test_ogr.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -51,7 +35,6 @@ namespace // Common fixture with test data struct test_ogr : public ::testing::Test { - std::string drv_shape_{"ESRI Shapefile"}; std::string data_{tut::common::data_basedir}; std::string data_tmp_{tut::common::tmp_basedir}; }; @@ -62,14 +45,6 @@ TEST_F(test_ogr, GetGDALDriverManager) ASSERT_TRUE(nullptr != GetGDALDriverManager()); } -// Test if Shapefile driver is registered -TEST_F(test_ogr, Shapefile_driver) -{ - GDALDriver *drv = - GetGDALDriverManager()->GetDriverByName(drv_shape_.c_str()); - ASSERT_TRUE(nullptr != drv); -} - template void testSpatialReferenceLeakOnCopy(OGRSpatialReference *poSRS) { @@ -94,6 +69,7 @@ void testSpatialReferenceLeakOnCopy(OGRSpatialReference *poSRS) ASSERT_GT(nCurCount, nLastCount); nLastCount = nCurCount; + // coverity[copy_assignment_call] value3 = value; ASSERT_EQ(nLastCount, poSRS->GetReferenceCount()); } @@ -287,7 +263,7 @@ template <> OGRPolyhedralSurface *make() template void testCopyEquals() { - T *poOrigin = make(); + auto poOrigin = std::unique_ptr(make()); ASSERT_TRUE(nullptr != poOrigin); T value2(*poOrigin); @@ -313,7 +289,8 @@ template void testCopyEquals() << poOrigin->getGeometryName() << ": assignment operator changed a value"; - OGRGeometryFactory::destroyGeometry(poOrigin); + value3 = T(); + ASSERT_TRUE(value3.IsEmpty()); } // Test if copy constructor and assignment operators succeeds on copying the @@ -338,6 +315,116 @@ TEST_F(test_ogr, SpatialReference_leak_copy_constructor) testCopyEquals(); } +// Test crazy usage of OGRGeometryCollection copy constructor +TEST_F(test_ogr, OGRGeometryCollection_copy_constructor_illegal_use) +{ + OGRGeometryCollection gc; + gc.addGeometryDirectly(new OGRPoint(1, 2)); + + OGRMultiPolygon mp; + mp.addGeometryDirectly(new OGRPolygon()); + + OGRGeometryCollection *mp_as_gc = ∓ + CPLErrorReset(); + { + CPLErrorHandlerPusher oPusher(CPLQuietErrorHandler); + // coverity[copy_assignment_call] + *mp_as_gc = gc; + } + EXPECT_STREQ(CPLGetLastErrorMsg(), + "Illegal use of OGRGeometryCollection::operator=(): trying to " + "assign an incompatible sub-geometry"); + EXPECT_TRUE(mp.IsEmpty()); +} + +// Test crazy usage of OGRCurvePolygon copy constructor +TEST_F(test_ogr, OGRCurvePolygon_copy_constructor_illegal_use) +{ + OGRCurvePolygon cp; + auto poCC = new OGRCircularString(); + poCC->addPoint(0, 0); + poCC->addPoint(1, 1); + poCC->addPoint(2, 0); + poCC->addPoint(1, -1); + poCC->addPoint(0, 0); + cp.addRingDirectly(poCC); + + OGRPolygon poly; + auto poLR = new OGRLinearRing(); + poLR->addPoint(0, 0); + poLR->addPoint(1, 1); + poLR->addPoint(2, 0); + poLR->addPoint(1, -1); + poLR->addPoint(0, 0); + poly.addRingDirectly(poLR); + + OGRCurvePolygon *poly_as_cp = &poly; + CPLErrorReset(); + { + CPLErrorHandlerPusher oPusher(CPLQuietErrorHandler); + // coverity[copy_assignment_call] + *poly_as_cp = cp; + } + EXPECT_STREQ(CPLGetLastErrorMsg(), + "Illegal use of OGRCurvePolygon::operator=(): trying to " + "assign an incompatible sub-geometry"); + EXPECT_TRUE(poly.IsEmpty()); +} + +template void testMove() +{ + auto poSRS = new OGRSpatialReference(); + { + auto poOrigin = std::unique_ptr(make()); + ASSERT_TRUE(nullptr != poOrigin); + poOrigin->assignSpatialReference(poSRS); + + T valueCopy(*poOrigin); + const int refCountBefore = poSRS->GetReferenceCount(); + T fromMoved(std::move(*poOrigin)); + EXPECT_EQ(poSRS->GetReferenceCount(), refCountBefore); + + ASSERT_TRUE(CPL_TO_BOOL(fromMoved.Equals(&valueCopy))) + << valueCopy.getGeometryName() + << ": move constructor changed a value"; + EXPECT_EQ(fromMoved.getSpatialReference(), poSRS); + + T valueCopy2(valueCopy); + EXPECT_EQ(valueCopy.getSpatialReference(), poSRS); + T value3; + const int refCountBefore2 = poSRS->GetReferenceCount(); + value3 = std::move(valueCopy); + EXPECT_EQ(poSRS->GetReferenceCount(), refCountBefore2); + + ASSERT_TRUE(CPL_TO_BOOL(value3.Equals(&valueCopy2))) + << valueCopy2.getGeometryName() + << ": move assignment operator changed a value"; + EXPECT_EQ(value3.getSpatialReference(), poSRS); + } + EXPECT_EQ(poSRS->GetReferenceCount(), 1); + poSRS->Release(); +} + +TEST_F(test_ogr, geometry_move) +{ + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); + testMove(); +} + TEST_F(test_ogr, geometry_get_point) { { @@ -1333,6 +1420,12 @@ TEST_F(test_ogr, OGRToOGCGeomType) // Test layer, dataset-feature and layer-feature iterators TEST_F(test_ogr, DatasetFeature_and_LayerFeature_iterators) { + if (!GDALGetDriverByName("ESRI Shapefile")) + { + GTEST_SKIP() << "ESRI Shapefile driver missing"; + return; + } + std::string file(data_ + SEP + "poly.shp"); GDALDatasetUniquePtr poDS(GDALDataset::Open(file.c_str(), GDAL_OF_VECTOR)); ASSERT_TRUE(poDS != nullptr); @@ -4201,4 +4294,208 @@ TEST_F(test_ogr, OGRCurve_reversePoints) } } +// Test OGRGeometryFactory::transformWithOptions() +TEST_F(test_ogr, transformWithOptions) +{ + // Projected CRS to national geographic CRS (not including poles or antimeridian) + auto [poGeom, err] = OGRGeometryFactory::createFromWkt( + "LINESTRING(700000 6600000, 700001 6600001)"); + ASSERT_NE(poGeom, nullptr); + + OGRSpatialReference oEPSG_2154; + oEPSG_2154.importFromEPSG(2154); // "RGF93 v1 / Lambert-93" + OGRSpatialReference oEPSG_4171; + oEPSG_4171.importFromEPSG(4171); // "RGF93 v1" + oEPSG_4171.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + auto poCT = std::unique_ptr( + OGRCreateCoordinateTransformation(&oEPSG_2154, &oEPSG_4171)); + OGRGeometryFactory::TransformWithOptionsCache oCache; + auto poNewGeom = + std::unique_ptr(OGRGeometryFactory::transformWithOptions( + poGeom.get(), poCT.get(), nullptr, oCache)); + ASSERT_NE(poNewGeom, nullptr); + EXPECT_NEAR(poNewGeom->toLineString()->getX(0), 3, 1e-8); + EXPECT_NEAR(poNewGeom->toLineString()->getY(0), 46.5, 1e-8); +} + +#ifdef HAVE_GEOS + +// Test OGRGeometryFactory::transformWithOptions() +TEST_F(test_ogr, transformWithOptions_GEOS) +{ + // Projected CRS to national geographic CRS including antimeridian + auto [poGeom, err] = OGRGeometryFactory::createFromWkt( + "LINESTRING(657630.64 4984896.17,815261.43 4990738.26)"); + ASSERT_NE(poGeom, nullptr); + + OGRSpatialReference oEPSG_6329; + oEPSG_6329.importFromEPSG(6329); // "NAD83(2011) / UTM zone 60N" + OGRSpatialReference oEPSG_6318; + oEPSG_6318.importFromEPSG(6318); // "NAD83(2011)" + oEPSG_6318.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + auto poCT = std::unique_ptr( + OGRCreateCoordinateTransformation(&oEPSG_6329, &oEPSG_6318)); + OGRGeometryFactory::TransformWithOptionsCache oCache; + auto poNewGeom = + std::unique_ptr(OGRGeometryFactory::transformWithOptions( + poGeom.get(), poCT.get(), nullptr, oCache)); + ASSERT_NE(poNewGeom, nullptr); + EXPECT_EQ(poNewGeom->getGeometryType(), wkbMultiLineString); + if (poNewGeom->getGeometryType() == wkbMultiLineString) + { + const auto poMLS = poNewGeom->toMultiLineString(); + EXPECT_EQ(poMLS->getNumGeometries(), 2); + if (poMLS->getNumGeometries() == 2) + { + const auto poLS = poMLS->getGeometryRef(0); + EXPECT_EQ(poLS->getNumPoints(), 2); + if (poLS->getNumPoints() == 2) + { + EXPECT_NEAR(poLS->getX(0), 179, 1e-6); + EXPECT_NEAR(poLS->getY(0), 45, 1e-6); + EXPECT_NEAR(poLS->getX(1), 180, 1e-6); + EXPECT_NEAR(poLS->getY(1), 45.004384301691303, 1e-6); + } + } + } +} +#endif + +// Test OGRCurvePolygon::addRingDirectly +TEST_F(test_ogr, OGRCurvePolygon_addRingDirectly) +{ + OGRCurvePolygon cp; + OGRGeometry *ring; + + // closed CircularString + OGRGeometryFactory::createFromWkt( + "CIRCULARSTRING (0 0, 1 1, 2 0, 1 -1, 0 0)", nullptr, &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(cp.addRingDirectly(ring->toCurve()), OGRERR_NONE); + + // open CircularString + OGRGeometryFactory::createFromWkt("CIRCULARSTRING (0 0, 1 1, 2 0)", nullptr, + &ring); + ASSERT_TRUE(ring); + { + CPLConfigOptionSetter oSetter("OGR_GEOMETRY_ACCEPT_UNCLOSED_RING", "NO", + false); + ASSERT_EQ(cp.addRingDirectly(ring->toCurve()), + OGRERR_UNSUPPORTED_GEOMETRY_TYPE); + } + EXPECT_EQ(cp.addRingDirectly(ring->toCurve()), OGRERR_NONE); + + // closed CompoundCurve + OGRGeometryFactory::createFromWkt( + "COMPOUNDCURVE( CIRCULARSTRING (0 0, 1 1, 2 0), (2 0, 0 0))", nullptr, + &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(cp.addRingDirectly(ring->toCurve()), OGRERR_NONE); + + // closed LineString + OGRGeometryFactory::createFromWkt("LINESTRING (0 0, 1 0, 1 1, 0 1, 0 0)", + nullptr, &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(cp.addRingDirectly(ring->toCurve()), OGRERR_NONE); + + // LinearRing + auto lr = std::make_unique(); + lr->addPoint(0, 0); + lr->addPoint(1, 0); + lr->addPoint(1, 1); + lr->addPoint(0, 1); + lr->addPoint(0, 0); + ASSERT_TRUE(ring); + ASSERT_EQ(cp.addRingDirectly(lr.get()), OGRERR_UNSUPPORTED_GEOMETRY_TYPE); +} + +// Test OGRPolygon::addRingDirectly +TEST_F(test_ogr, OGRPolygon_addRingDirectly) +{ + OGRPolygon p; + OGRGeometry *ring; + + // closed CircularString + OGRGeometryFactory::createFromWkt( + "CIRCULARSTRING (0 0, 1 1, 2 0, 1 -1, 0 0)", nullptr, &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(p.addRingDirectly(ring->toCurve()), + OGRERR_UNSUPPORTED_GEOMETRY_TYPE); + delete ring; + + // closed LineString + OGRGeometryFactory::createFromWkt("LINESTRING (0 0, 1 0, 1 1, 0 1, 0 0)", + nullptr, &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(p.addRingDirectly(ring->toCurve()), + OGRERR_UNSUPPORTED_GEOMETRY_TYPE); + delete ring; + + // open LineString + OGRGeometryFactory::createFromWkt("LINESTRING (0 0, 1 0)", nullptr, &ring); + ASSERT_TRUE(ring); + EXPECT_EQ(p.addRingDirectly(ring->toCurve()), + OGRERR_UNSUPPORTED_GEOMETRY_TYPE); + delete ring; + + // LinearRing + auto lr = std::make_unique(); + lr->addPoint(0, 0); + lr->addPoint(1, 0); + lr->addPoint(1, 1); + lr->addPoint(0, 1); + lr->addPoint(0, 0); + ASSERT_EQ(p.addRingDirectly(lr.release()), OGRERR_NONE); +} + +TEST_F(test_ogr, OGRFeature_SetGeometry) +{ + OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn(); + poFeatureDefn->Reference(); + + OGRFeature oFeat(poFeatureDefn); + auto [poGeom, err] = OGRGeometryFactory::createFromWkt("POINT (3 7)"); + ASSERT_EQ(err, OGRERR_NONE); + + ASSERT_EQ(oFeat.SetGeometry(std::move(poGeom)), OGRERR_NONE); + EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getX(), 3); + EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getY(), 7); + + // set it again to make sure previous feature geometry is freed + std::tie(poGeom, err) = OGRGeometryFactory::createFromWkt("POINT (2 8)"); + ASSERT_EQ(err, OGRERR_NONE); + ASSERT_EQ(oFeat.SetGeometry(std::move(poGeom)), OGRERR_NONE); + EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getX(), 2); + EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getY(), 8); + + poFeatureDefn->Release(); +} + +TEST_F(test_ogr, OGRFeature_SetGeomField) +{ + OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn(); + poFeatureDefn->Reference(); + + OGRGeomFieldDefn oGeomField("second", wkbPoint); + poFeatureDefn->AddGeomFieldDefn(&oGeomField); + + OGRFeature oFeat(poFeatureDefn); + + // failure + { + auto [poGeom, err] = OGRGeometryFactory::createFromWkt("POINT (3 7)"); + ASSERT_EQ(err, OGRERR_NONE); + EXPECT_EQ(oFeat.SetGeomField(13, std::move(poGeom)), OGRERR_FAILURE); + } + + // success + { + auto [poGeom, err] = OGRGeometryFactory::createFromWkt("POINT (3 7)"); + ASSERT_EQ(err, OGRERR_NONE); + EXPECT_EQ(oFeat.SetGeomField(1, std::move(poGeom)), OGRERR_NONE); + } + + poFeatureDefn->Release(); +} + } // namespace diff --git a/autotest/cpp/test_ogr_geometry_stealing.cpp b/autotest/cpp/test_ogr_geometry_stealing.cpp index 0c0e861fed88..5edd98542617 100644 --- a/autotest/cpp/test_ogr_geometry_stealing.cpp +++ b/autotest/cpp/test_ogr_geometry_stealing.cpp @@ -7,24 +7,7 @@ ****************************************************************************** * Copyright (C) 2022 mathieu17g * - * 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. + * SPDX-License-Identifier: MIT ******************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_ogr_geos.cpp b/autotest/cpp/test_ogr_geos.cpp index 1d2c5afcf474..461947f200b5 100644 --- a/autotest/cpp/test_ogr_geos.cpp +++ b/autotest/cpp/test_ogr_geos.cpp @@ -8,23 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_ogr_organize_polygons.cpp b/autotest/cpp/test_ogr_organize_polygons.cpp index e4b1ccb51042..64780361dc8c 100644 --- a/autotest/cpp/test_ogr_organize_polygons.cpp +++ b/autotest/cpp/test_ogr_organize_polygons.cpp @@ -7,23 +7,7 @@ ********************************************************************** * Copyright (c) 2023, ISciences LLC * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_ogr_shape.cpp b/autotest/cpp/test_ogr_shape.cpp index f70c05c0cf64..9cdf2e165294 100644 --- a/autotest/cpp/test_ogr_shape.cpp +++ b/autotest/cpp/test_ogr_shape.cpp @@ -8,23 +8,7 @@ // Copyright (c) 2006, Mateusz Loskot // Copyright (c) 2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -63,6 +47,8 @@ struct test_ogr_shape : public ::testing::Test void TearDown() override { + if (!drv_) + return; OGRDataSourceH ds = OGR_Dr_CreateDataSource(drv_, data_tmp_.c_str(), nullptr); if (ds == nullptr) @@ -545,7 +531,7 @@ TEST_F(test_ogr_shape, spatial_filtering) OGR_DS_Destroy(ds); } -TEST(test_ogr_shape_gdal, create) +TEST_F(test_ogr_shape, create_gdal) { GDALDriver *shpDriver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile"); diff --git a/autotest/cpp/test_ogr_swq.cpp b/autotest/cpp/test_ogr_swq.cpp index 73074b9e13c6..483ce55fa113 100644 --- a/autotest/cpp/test_ogr_swq.cpp +++ b/autotest/cpp/test_ogr_swq.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -154,11 +138,10 @@ class PushNotOperationDownToStackFixture std::make_tuple("NOT(1 <= 2)", "1 > 2"), std::make_tuple("NOT(1 < 2)", "1 >= 2"), std::make_tuple("NOT(NOT(1))", "1"), - std::make_tuple("NOT(1 AND 2)", "(NOT (1)) OR (NOT (2))"), - std::make_tuple("NOT(1 OR 2)", "(NOT (1)) AND (NOT (2))"), - std::make_tuple("3 AND NOT(1 OR 2)", - "3 AND ((NOT (1)) AND (NOT (2)))"), - std::make_tuple("NOT(NOT(1 = 2) OR 2)", "(1 = 2) AND (NOT (2))"), + std::make_tuple("NOT(1 AND 2)", "(NOT 1) OR (NOT 2)"), + std::make_tuple("NOT(1 OR 2)", "(NOT 1) AND (NOT 2)"), + std::make_tuple("3 AND NOT(1 OR 2)", "3 AND ((NOT 1) AND (NOT 2))"), + std::make_tuple("NOT(NOT(1 = 2) OR 2)", "(1 = 2) AND (NOT 2)"), std::make_tuple("1", "1"), }; } diff --git a/autotest/cpp/test_ogr_wkb.cpp b/autotest/cpp/test_ogr_wkb.cpp index ed86e66fd6a6..bff0f2df08a0 100644 --- a/autotest/cpp/test_ogr_wkb.cpp +++ b/autotest/cpp/test_ogr_wkb.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" @@ -524,4 +508,354 @@ INSTANTIATE_TEST_SUITE_P( OGRWKBIntersectsPessimisticFixture::ParamType> &l_info) { return std::get<6>(l_info.param); }); +class OGRWKBTransformFixture + : public test_ogr_wkb, + public ::testing::WithParamInterface< + std::tuple> +{ + public: + static std::vector< + std::tuple> + GetTupleValues() + { + return { + std::make_tuple("POINT EMPTY", wkbNDR, "POINT EMPTY", + "POINT_EMPTY_NDR"), + std::make_tuple("POINT EMPTY", wkbXDR, "POINT EMPTY", + "POINT_EMPTY_XDR"), + std::make_tuple("POINT (1 2)", wkbNDR, "POINT (2 4)", "POINT_NDR"), + std::make_tuple("POINT (1 2)", wkbXDR, "POINT (2 4)", "POINT_XDR"), + std::make_tuple("POINT Z EMPTY", wkbNDR, "POINT Z EMPTY", + "POINT_Z_EMPTY_NDR"), + std::make_tuple("POINT Z EMPTY", wkbXDR, "POINT Z EMPTY", + "POINT_Z_EMPTY_XDR"), + std::make_tuple("POINT Z (1 2 3)", wkbNDR, "POINT Z (2 4 6)", + "POINT_Z_NDR"), + std::make_tuple("POINT Z (1 2 3)", wkbXDR, "POINT Z (2 4 6)", + "POINT_Z_XDR"), + std::make_tuple("POINT M EMPTY", wkbNDR, "POINT M EMPTY", + "POINT_M_EMPTY_NDR"), + std::make_tuple("POINT M EMPTY", wkbXDR, "POINT M EMPTY", + "POINT_M_EMPTY_XDR"), + std::make_tuple("POINT M (1 2 -10)", wkbNDR, "POINT M (2 4 -10)", + "POINT_M_NDR"), + std::make_tuple("POINT M (1 2 -10)", wkbXDR, "POINT M (2 4 -10)", + "POINT_M_XDR"), + std::make_tuple("POINT ZM EMPTY", wkbNDR, "POINT ZM EMPTY", + "POINT_ZM_EMPTY_NDR"), + std::make_tuple("POINT ZM EMPTY", wkbXDR, "POINT ZM EMPTY", + "POINT_ZM_EMPTY_XDR"), + std::make_tuple("POINT ZM (1 2 3 10)", wkbNDR, + "POINT ZM (2 4 6 10)", "POINT_ZM_NDR"), + std::make_tuple("POINT ZM (1 2 3 10)", wkbXDR, + "POINT ZM (2 4 6 10)", "POINT_ZM_XDR"), + + std::make_tuple("LINESTRING EMPTY", wkbNDR, "LINESTRING EMPTY", + "LINESTRING_EMPTY"), + std::make_tuple("LINESTRING (1 2,11 12)", wkbNDR, + "LINESTRING (2 4,12 14)", "LINESTRING_NDR"), + std::make_tuple("LINESTRING (1 2,11 12)", wkbXDR, + "LINESTRING (2 4,12 14)", "LINESTRING_XDR"), + std::make_tuple("LINESTRING Z EMPTY", wkbNDR, "LINESTRING Z EMPTY", + "LINESTRING_Z_EMPTY"), + std::make_tuple("LINESTRING Z (1 2 3,11 12 13)", wkbNDR, + "LINESTRING Z (2 4 6,12 14 16)", + "LINESTRING_Z_NDR"), + std::make_tuple("LINESTRING Z (1 2 3,11 12 13)", wkbXDR, + "LINESTRING Z (2 4 6,12 14 16)", + "LINESTRING_Z_XDR"), + std::make_tuple("LINESTRING M EMPTY", wkbNDR, "LINESTRING M EMPTY", + "LINESTRING_M_EMPTY"), + std::make_tuple("LINESTRING M (1 2 -10,11 12 -20)", wkbNDR, + "LINESTRING M (2 4 -10,12 14 -20)", + "LINESTRING_M_NDR"), + std::make_tuple("LINESTRING M (1 2 -10,11 12 -20)", wkbXDR, + "LINESTRING M (2 4 -10,12 14 -20)", + "LINESTRING_M_XDR"), + std::make_tuple("LINESTRING ZM EMPTY", wkbNDR, + "LINESTRING ZM EMPTY", "LINESTRING_ZM_EMPTY"), + std::make_tuple("LINESTRING ZM (1 2 3 -10,11 12 13 -20)", wkbNDR, + "LINESTRING ZM (2 4 6 -10,12 14 16 -20)", + "LINESTRING_ZM_NDR"), + std::make_tuple("LINESTRING ZM (1 2 3 -10,11 12 13 -20)", wkbXDR, + "LINESTRING ZM (2 4 6 -10,12 14 16 -20)", + "LINESTRING_ZM_XDR"), + + // I know the polygon is invalid, but this is enough for our purposes + std::make_tuple("POLYGON EMPTY", wkbNDR, "POLYGON EMPTY", + "POLYGON_EMPTY"), + std::make_tuple("POLYGON ((1 2,11 12))", wkbNDR, + "POLYGON ((2 4,12 14))", "POLYGON_NDR"), + std::make_tuple("POLYGON ((1 2,11 12))", wkbXDR, + "POLYGON ((2 4,12 14))", "POLYGON_XDR"), + std::make_tuple("POLYGON ((1 2,11 12),(21 22,31 32))", wkbNDR, + "POLYGON ((2 4,12 14),(22 24,32 34))", + "POLYGON_TWO_RINGS"), + std::make_tuple("POLYGON Z EMPTY", wkbNDR, "POLYGON Z EMPTY", + "POLYGON_Z_EMPTY"), + std::make_tuple("POLYGON Z ((1 2 3,11 12 13))", wkbNDR, + "POLYGON Z ((2 4 6,12 14 16))", "POLYGON_Z_NDR"), + std::make_tuple("POLYGON Z ((1 2 3,11 12 13))", wkbXDR, + "POLYGON Z ((2 4 6,12 14 16))", "POLYGON_Z_XDR"), + std::make_tuple("POLYGON M EMPTY", wkbNDR, "POLYGON M EMPTY", + "POLYGON_M_EMPTY"), + std::make_tuple("POLYGON M ((1 2 -10,11 12 -20))", wkbNDR, + "POLYGON M ((2 4 -10,12 14 -20))", "POLYGON_M_NDR"), + std::make_tuple("POLYGON M ((1 2 -10,11 12 -20))", wkbXDR, + "POLYGON M ((2 4 -10,12 14 -20))", "POLYGON_M_XDR"), + std::make_tuple("POLYGON ZM EMPTY", wkbNDR, "POLYGON ZM EMPTY", + "POLYGON_ZM_EMPTY"), + std::make_tuple("POLYGON ZM ((1 2 3 -10,11 12 13 -20))", wkbNDR, + "POLYGON ZM ((2 4 6 -10,12 14 16 -20))", + "POLYGON_ZM_NDR"), + std::make_tuple("POLYGON ZM ((1 2 3 -10,11 12 13 -20))", wkbXDR, + "POLYGON ZM ((2 4 6 -10,12 14 16 -20))", + "POLYGON_ZM_XDR"), + + std::make_tuple("MULTIPOINT EMPTY", wkbNDR, "MULTIPOINT EMPTY", + "MULTIPOINT_EMPTY_NDR"), + std::make_tuple("MULTIPOINT ((1 2),(11 12))", wkbNDR, + "MULTIPOINT ((2 4),(12 14))", "MULTIPOINT_NDR"), + std::make_tuple("MULTIPOINT Z ((1 2 3),(11 12 13))", wkbXDR, + "MULTIPOINT Z ((2 4 6),(12 14 16))", + "MULTIPOINT_Z_XDR"), + + std::make_tuple("MULTILINESTRING ((1 2,11 12))", wkbNDR, + "MULTILINESTRING ((2 4,12 14))", + "MULTILINESTRING_NDR"), + + std::make_tuple("MULTIPOLYGON (((1 2,11 12)))", wkbNDR, + "MULTIPOLYGON (((2 4,12 14)))", "MULTIPOLYGON_NDR"), + + std::make_tuple("GEOMETRYCOLLECTION (POLYGON ((1 2,11 12)))", + wkbNDR, + "GEOMETRYCOLLECTION (POLYGON ((2 4,12 14)))", + "GEOMETRYCOLLECTION_NDR"), + + std::make_tuple("CIRCULARSTRING (1 2,11 12,21 22)", wkbNDR, + "CIRCULARSTRING (2 4,12 14,22 24)", + "CIRCULARSTRING_NDR"), + + std::make_tuple("COMPOUNDCURVE ((1 2,11 12))", wkbNDR, + "COMPOUNDCURVE ((2 4,12 14))", "COMPOUNDCURVE_NDR"), + + std::make_tuple("CURVEPOLYGON ((1 2,11 12,21 22,1 2))", wkbNDR, + "CURVEPOLYGON ((2 4,12 14,22 24,2 4))", + "CURVEPOLYGON_NDR"), + + std::make_tuple("MULTICURVE ((1 2,11 12))", wkbNDR, + "MULTICURVE ((2 4,12 14))", "MULTICURVE_NDR"), + + std::make_tuple("MULTISURFACE (((1 2,11 12)))", wkbNDR, + "MULTISURFACE (((2 4,12 14)))", "MULTISURFACE_NDR"), + + std::make_tuple("TRIANGLE ((1 2,11 12,21 22,1 2))", wkbNDR, + "TRIANGLE ((2 4,12 14,22 24,2 4))", "TRIANGLE_NDR"), + + std::make_tuple("POLYHEDRALSURFACE (((1 2,11 12,21 22,1 2)))", + wkbNDR, + "POLYHEDRALSURFACE (((2 4,12 14,22 24,2 4)))", + "POLYHEDRALSURFACE_NDR"), + + std::make_tuple("TIN (((1 2,11 12,21 22,1 2)))", wkbNDR, + "TIN (((2 4,12 14,22 24,2 4)))", "TIN_NDR"), + }; + } +}; + +struct MyCT final : public OGRCoordinateTransformation +{ + const bool m_bSuccess; + + explicit MyCT(bool bSuccess = true) : m_bSuccess(bSuccess) + { + } + + const OGRSpatialReference *GetSourceCS() const override + { + return nullptr; + } + + const OGRSpatialReference *GetTargetCS() const override + { + return nullptr; + } + + int Transform(size_t nCount, double *x, double *y, double *z, double *, + int *pabSuccess) override + { + for (size_t i = 0; i < nCount; ++i) + { + x[i] += 1; + y[i] += 2; + if (z) + z[i] += 3; + if (pabSuccess) + pabSuccess[i] = m_bSuccess; + } + return true; + } + + OGRCoordinateTransformation *Clone() const override + { + return new MyCT(); + } + + OGRCoordinateTransformation *GetInverse() const override + { + return nullptr; + } // unused +}; + +TEST_P(OGRWKBTransformFixture, test) +{ + const char *pszInput = std::get<0>(GetParam()); + OGRwkbByteOrder eByteOrder = std::get<1>(GetParam()); + const char *pszOutput = std::get<2>(GetParam()); + + MyCT oCT; + oCT.GetSourceCS(); // just for code coverage purpose + oCT.GetTargetCS(); // just for code coverage purpose + delete oCT.Clone(); // just for code coverage purpose + delete oCT.GetInverse(); // just for code coverage purpose + + OGRGeometry *poGeom = nullptr; + EXPECT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom), + OGRERR_NONE); + ASSERT_TRUE(poGeom != nullptr); + std::vector abyWkb(poGeom->WkbSize()); + poGeom->exportToWkb(eByteOrder, abyWkb.data(), wkbVariantIso); + delete poGeom; + + OGRWKBTransformCache oCache; + OGREnvelope3D sEnv; + EXPECT_TRUE( + OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv)); + const auto abyWkbOri = abyWkb; + + poGeom = nullptr; + OGRGeometryFactory::createFromWkb(abyWkb.data(), nullptr, &poGeom, + abyWkb.size()); + ASSERT_TRUE(poGeom != nullptr); + char *pszWKT = nullptr; + poGeom->exportToWkt(&pszWKT, wkbVariantIso); + delete poGeom; + EXPECT_STREQ(pszWKT, pszOutput); + CPLFree(pszWKT); + + { + CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler); + + // Truncated geometry + for (size_t i = 0; i < abyWkb.size(); ++i) + { + abyWkb = abyWkbOri; + EXPECT_FALSE(OGRWKBTransform(abyWkb.data(), i, &oCT, oCache, sEnv)); + } + + // Check altering all bytes + for (size_t i = 0; i < abyWkb.size(); ++i) + { + abyWkb = abyWkbOri; + abyWkb[i] = 0xff; + CPL_IGNORE_RET_VAL(OGRWKBTransform(abyWkb.data(), abyWkb.size(), + &oCT, oCache, sEnv)); + } + + if (abyWkb.size() > 9) + { + abyWkb = abyWkbOri; + if (!STARTS_WITH(pszInput, "POINT")) + { + // Corrupt number of sub-geometries + abyWkb[5] = 0xff; + abyWkb[6] = 0xff; + abyWkb[7] = 0xff; + abyWkb[8] = 0xff; + EXPECT_FALSE(OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, + oCache, sEnv)); + } + } + } +} + +INSTANTIATE_TEST_SUITE_P( + test_ogr_wkb, OGRWKBTransformFixture, + ::testing::ValuesIn(OGRWKBTransformFixture::GetTupleValues()), + [](const ::testing::TestParamInfo + &l_info) { return std::get<3>(l_info.param); }); + +TEST_F(test_ogr_wkb, OGRWKBTransformFixture_rec_collection) +{ + std::vector abyWkb; + constexpr int BEYOND_ALLOWED_RECURSION_LEVEL = 128; + for (int i = 0; i < BEYOND_ALLOWED_RECURSION_LEVEL; ++i) + { + abyWkb.push_back(wkbNDR); + abyWkb.push_back(wkbGeometryCollection); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(1); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + } + { + abyWkb.push_back(wkbNDR); + abyWkb.push_back(wkbGeometryCollection); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + abyWkb.push_back(0); + } + + MyCT oCT; + OGRWKBTransformCache oCache; + OGREnvelope3D sEnv; + EXPECT_FALSE( + OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv)); +} + +TEST_F(test_ogr_wkb, OGRWKBTransformFixture_ct_failure) +{ + MyCT oCT(/* bSuccess = */ false); + OGRWKBTransformCache oCache; + OGREnvelope3D sEnv; + { + OGRPoint p(1, 2); + std::vector abyWkb(p.WkbSize()); + static_cast(p).exportToWkb(wkbNDR, abyWkb.data(), + wkbVariantIso); + + EXPECT_FALSE( + OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv)); + } + { + OGRLineString ls; + ls.addPoint(1, 2); + std::vector abyWkb(ls.WkbSize()); + static_cast(ls).exportToWkb(wkbNDR, abyWkb.data(), + wkbVariantIso); + + EXPECT_FALSE( + OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv)); + } + { + OGRPolygon p; + auto poLR = std::make_unique(); + poLR->addPoint(1, 2); + p.addRing(std::move(poLR)); + std::vector abyWkb(p.WkbSize()); + static_cast(p).exportToWkb(wkbNDR, abyWkb.data(), + wkbVariantIso); + + EXPECT_FALSE( + OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv)); + } +} + } // namespace diff --git a/autotest/cpp/test_osr.cpp b/autotest/cpp/test_osr.cpp index 23aed5a65307..0a03b2619ac9 100644 --- a/autotest/cpp/test_osr.cpp +++ b/autotest/cpp/test_osr.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_osr_ct.cpp b/autotest/cpp/test_osr_ct.cpp index ee8a4066e757..e112250f18fb 100644 --- a/autotest/cpp/test_osr_ct.cpp +++ b/autotest/cpp/test_osr_ct.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_osr_pci.cpp b/autotest/cpp/test_osr_pci.cpp index b75e47e08974..b2c5f8b0fba1 100644 --- a/autotest/cpp/test_osr_pci.cpp +++ b/autotest/cpp/test_osr_pci.cpp @@ -8,23 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_osr_proj4.cpp b/autotest/cpp/test_osr_proj4.cpp index 18ddf15ece45..0fff5fd1771a 100644 --- a/autotest/cpp/test_osr_proj4.cpp +++ b/autotest/cpp/test_osr_proj4.cpp @@ -8,23 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2006, Mateusz Loskot /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_osr_set_proj_search_paths.cpp b/autotest/cpp/test_osr_set_proj_search_paths.cpp index d3c0b0538775..7a41c072130d 100644 --- a/autotest/cpp/test_osr_set_proj_search_paths.cpp +++ b/autotest/cpp/test_osr_set_proj_search_paths.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/autotest/cpp/test_triangulation.cpp b/autotest/cpp/test_triangulation.cpp index 9460140ac962..0241c2df11b6 100644 --- a/autotest/cpp/test_triangulation.cpp +++ b/autotest/cpp/test_triangulation.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/test_utilities.cpp b/autotest/cpp/test_utilities.cpp index 52849efcb387..b3dedd60b623 100644 --- a/autotest/cpp/test_utilities.cpp +++ b/autotest/cpp/test_utilities.cpp @@ -7,23 +7,7 @@ /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_unit_test.h" diff --git a/autotest/cpp/test_viewshed.cpp b/autotest/cpp/test_viewshed.cpp index ec5846501f9d..484ad9c4746b 100644 --- a/autotest/cpp/test_viewshed.cpp +++ b/autotest/cpp/test_viewshed.cpp @@ -6,23 +6,7 @@ // /////////////////////////////////////////////////////////////////////////////// /* - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/autotest/cpp/testblockcache.cpp b/autotest/cpp/testblockcache.cpp index 36607159fc0e..2f0459375294 100644 --- a/autotest/cpp/testblockcache.cpp +++ b/autotest/cpp/testblockcache.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef DEBUG diff --git a/autotest/cpp/testblockcachelimits.cpp b/autotest/cpp/testblockcachelimits.cpp index 4d188fde56a7..6531c2cd6a1b 100644 --- a/autotest/cpp/testblockcachelimits.cpp +++ b/autotest/cpp/testblockcachelimits.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/testblockcachewrite.cpp b/autotest/cpp/testblockcachewrite.cpp index 238c8ddc03a7..e6141ca9dc3b 100644 --- a/autotest/cpp/testblockcachewrite.cpp +++ b/autotest/cpp/testblockcachewrite.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/testclosedondestroydm.cpp b/autotest/cpp/testclosedondestroydm.cpp index 3f001d1c9902..efc7e056456c 100644 --- a/autotest/cpp/testclosedondestroydm.cpp +++ b/autotest/cpp/testclosedondestroydm.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/testcopywords.cpp b/autotest/cpp/testcopywords.cpp index d145098b0d56..f69947ba942c 100644 --- a/autotest/cpp/testcopywords.cpp +++ b/autotest/cpp/testcopywords.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2009-2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/testdestroy.cpp b/autotest/cpp/testdestroy.cpp index bc97d765baa7..823413681538 100644 --- a/autotest/cpp/testdestroy.cpp +++ b/autotest/cpp/testdestroy.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal.h" diff --git a/autotest/cpp/testlog.cpp b/autotest/cpp/testlog.cpp index 27936524a12a..0f03b458f432 100644 --- a/autotest/cpp/testlog.cpp +++ b/autotest/cpp/testlog.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2021, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/autotest/cpp/testmultithreadedwriting.cpp b/autotest/cpp/testmultithreadedwriting.cpp index 175fa51211cc..cd633afa19ec 100644 --- a/autotest/cpp/testmultithreadedwriting.cpp +++ b/autotest/cpp/testmultithreadedwriting.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2016, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_multiproc.h" diff --git a/autotest/cpp/testthreadcond.cpp b/autotest/cpp/testthreadcond.cpp index a4005d819b81..557b404510d9 100644 --- a/autotest/cpp/testthreadcond.cpp +++ b/autotest/cpp/testthreadcond.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef DEBUG diff --git a/autotest/cpp/testvirtualmem.cpp b/autotest/cpp/testvirtualmem.cpp index 5f72fdba29f9..e9f30dc55b5b 100644 --- a/autotest/cpp/testvirtualmem.cpp +++ b/autotest/cpp/testvirtualmem.cpp @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2014, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_multiproc.h" diff --git a/autotest/gcore/asyncreader.py b/autotest/gcore/asyncreader.py index 2ea1f098a9a7..f8e42235490f 100755 --- a/autotest/gcore/asyncreader.py +++ b/autotest/gcore/asyncreader.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/basic_test.py b/autotest/gcore/basic_test.py index 2719fc963dcc..aad4af0b5abc 100755 --- a/autotest/gcore/basic_test.py +++ b/autotest/gcore/basic_test.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -192,17 +176,20 @@ def test_basic_test_8(): license_text.startswith("GDAL/OGR is released under the MIT license") or "GDAL/OGR Licensing" in license_text ) - - # Use a subprocess to avoid the cached license text - env = os.environ.copy() - env["GDAL_DATA"] = "tmp" - with open("tmp/LICENSE.TXT", "wt") as f: - f.write("fake_license") - license_text = subprocess.check_output( - [sys.executable, "basic_test_subprocess.py"], env=env - ).decode("utf-8") - os.unlink("tmp/LICENSE.TXT") - assert license_text.startswith("fake_license") + if "EMBED_RESOURCE_FILES=YES" in gdal.VersionInfo("BUILD_INFO"): + assert len(license_text) > 1000 + + if "USE_ONLY_EMBEDDED_RESOURCE_FILES=YES" not in gdal.VersionInfo("BUILD_INFO"): + # Use a subprocess to avoid the cached license text + env = os.environ.copy() + env["GDAL_DATA"] = "tmp" + with open("tmp/LICENSE.TXT", "wt") as f: + f.write("fake_license") + license_text = subprocess.check_output( + [sys.executable, "basic_test_subprocess.py"], env=env + ).decode("utf-8") + os.unlink("tmp/LICENSE.TXT") + assert license_text.startswith("fake_license") ############################################################################### @@ -235,7 +222,7 @@ def test_basic_test_9(): # Test gdal.PushErrorHandler() with a Python error handler as a method (#5186) -class my_python_error_handler_class(object): +class my_python_error_handler_class: def __init__(self): self.eErrClass = None self.err_no = None @@ -990,3 +977,32 @@ def test_band_getitem(): with pytest.raises(IndexError): ds[5] + + +def test_colorinterp(): + + d = {} + for c in range(gdal.GCI_Max + 1): + name = gdal.GetColorInterpretationName(c) + assert name not in d + d[name] = c + assert gdal.GetColorInterpretationByName(name) == c + + +def test_ComputeMinMaxLocation(): + + ds = gdal.Open("data/byte.tif") + ret = ds.GetRasterBand(1).ComputeMinMaxLocation() + assert ( + ret.min == 74 + and ret.max == 255 + and ret.minX == 9 + and ret.minY == 17 + and ret.maxX == 2 + and ret.maxY == 18 + ) + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 1, gdal.GDT_Float64) + ds.GetRasterBand(1).Fill(float("nan")) + ret = ds.GetRasterBand(1).ComputeMinMaxLocation() + assert ret is None diff --git a/autotest/gcore/basic_test_subprocess.py b/autotest/gcore/basic_test_subprocess.py index 34e2a8cd23a4..254a29e4c354 100755 --- a/autotest/gcore/basic_test_subprocess.py +++ b/autotest/gcore/basic_test_subprocess.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### from osgeo import gdal diff --git a/autotest/gcore/cog.py b/autotest/gcore/cog.py index d89a6624d473..c65989e7cdcc 100755 --- a/autotest/gcore/cog.py +++ b/autotest/gcore/cog.py @@ -10,25 +10,10 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### +import os import struct import sys @@ -574,7 +559,7 @@ def my_cbk(pct, _, arg): filename2 = directory + "/cog2.tif" src_ds = gdal.Open(filename) - class my_error_handler(object): + class my_error_handler: def __init__(self): self.debug_msg_list = [] self.other_msg_list = [] @@ -1951,3 +1936,29 @@ def test_cog_mask_band_overviews(tmp_vsimem): assert ds.GetRasterBand(1).IsMaskBand() assert ds.GetRasterBand(1).GetOverview(0).IsMaskBand() assert ds.GetRasterBand(1).GetOverview(1).IsMaskBand() + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. + + +@pytest.mark.parametrize( + "src_filename,creation_options", + [ + ("data/cog/byte_little_endian_golden.tif", []), + ( + "data/cog/byte_little_endian_blocksize_16_predictor_standard_golden.tif", + ["BLOCKSIZE=16", "PREDICTOR=STANDARD"], + ), + ], +) +def test_cog_write_check_golden_file(tmp_path, src_filename, creation_options): + + out_filename = str(tmp_path / "test.tif") + with gdal.config_option("GDAL_TIFF_ENDIANNESS", "LITTLE"): + with gdal.Open(src_filename) as src_ds: + gdal.GetDriverByName("COG").CreateCopy( + out_filename, src_ds, options=creation_options + ) + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size + assert open(src_filename, "rb").read() == open(out_filename, "rb").read() diff --git a/autotest/gcore/colortable.py b/autotest/gcore/colortable.py index 0607814e0c9b..6390d38260bf 100755 --- a/autotest/gcore/colortable.py +++ b/autotest/gcore/colortable.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/data/cog/byte_little_endian_blocksize_16_predictor_standard_golden.tif b/autotest/gcore/data/cog/byte_little_endian_blocksize_16_predictor_standard_golden.tif new file mode 100644 index 000000000000..aaade76e71f7 Binary files /dev/null and b/autotest/gcore/data/cog/byte_little_endian_blocksize_16_predictor_standard_golden.tif differ diff --git a/autotest/gcore/data/cog/byte_little_endian_golden.tif b/autotest/gcore/data/cog/byte_little_endian_golden.tif new file mode 100644 index 000000000000..4ace013ced02 Binary files /dev/null and b/autotest/gcore/data/cog/byte_little_endian_golden.tif differ diff --git a/autotest/gcore/data/gtiff/byte_little_endian_golden.tif b/autotest/gcore/data/gtiff/byte_little_endian_golden.tif new file mode 100644 index 000000000000..a4cbc947432c Binary files /dev/null and b/autotest/gcore/data/gtiff/byte_little_endian_golden.tif differ diff --git a/autotest/gcore/data/gtiff/byte_little_endian_tiled_lzw_golden.tif b/autotest/gcore/data/gtiff/byte_little_endian_tiled_lzw_golden.tif new file mode 100644 index 000000000000..b43311f0e16a Binary files /dev/null and b/autotest/gcore/data/gtiff/byte_little_endian_tiled_lzw_golden.tif differ diff --git a/autotest/gcore/data/gtiff/complex_non_zero_real_zero_imag.tif b/autotest/gcore/data/gtiff/complex_non_zero_real_zero_imag.tif new file mode 100644 index 000000000000..727a5d6178df Binary files /dev/null and b/autotest/gcore/data/gtiff/complex_non_zero_real_zero_imag.tif differ diff --git a/autotest/gcore/data/gtiff/float32_little_endian_golden.tif b/autotest/gcore/data/gtiff/float32_little_endian_golden.tif new file mode 100644 index 000000000000..96e3dfd31339 Binary files /dev/null and b/autotest/gcore/data/gtiff/float32_little_endian_golden.tif differ diff --git a/autotest/gcore/data/gtiff/uint16_little_endian_golden.tif b/autotest/gcore/data/gtiff/uint16_little_endian_golden.tif new file mode 100644 index 000000000000..2ea26292221b Binary files /dev/null and b/autotest/gcore/data/gtiff/uint16_little_endian_golden.tif differ diff --git a/autotest/gcore/data/gtiff/unknown_colorinterp.tif b/autotest/gcore/data/gtiff/unknown_colorinterp.tif new file mode 100644 index 000000000000..02466ea4db36 Binary files /dev/null and b/autotest/gcore/data/gtiff/unknown_colorinterp.tif differ diff --git a/autotest/gcore/data/tar_of_tar_gzip.tar b/autotest/gcore/data/tar_of_tar_gzip.tar new file mode 100644 index 000000000000..ed18401a2bc5 Binary files /dev/null and b/autotest/gcore/data/tar_of_tar_gzip.tar differ diff --git a/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag.vrt b/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag.vrt new file mode 100644 index 000000000000..21be5ee9f10d --- /dev/null +++ b/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag.vrt @@ -0,0 +1,12 @@ + + PROJCS["WGS 84 / UTM zone 11N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32611"]] + 2.1520000000000000e+05, 3.0000000000000000e+01, 0.0000000000000000e+00, 4.3975000000000000e+06, 0.0000000000000000e+00, -3.0000000000000000e+01 + + Gray + + 0 + ../gtiff/complex_non_zero_real_zero_imag.tif + 1 + + + diff --git a/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag_as_float32.vrt b/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag_as_float32.vrt new file mode 100644 index 000000000000..36d3fd34ddf6 --- /dev/null +++ b/autotest/gcore/data/vrt/complex_non_zero_real_zero_imag_as_float32.vrt @@ -0,0 +1,12 @@ + + PROJCS["WGS 84 / UTM zone 11N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32611"]] + 2.1520000000000000e+05, 3.0000000000000000e+01, 0.0000000000000000e+00, 4.3975000000000000e+06, 0.0000000000000000e+00, -3.0000000000000000e+01 + + Gray + + 0 + ../gtiff/complex_non_zero_real_zero_imag.tif + 1 + + + diff --git a/autotest/gcore/data/vrt/nested_VRTDataset.vrt b/autotest/gcore/data/vrt/nested_VRTDataset.vrt new file mode 100644 index 000000000000..49a5ff70aef2 --- /dev/null +++ b/autotest/gcore/data/vrt/nested_VRTDataset.vrt @@ -0,0 +1,24 @@ + + PROJCS["NAD27 / UTM zone 11N",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213898,AUTHORITY["EPSG","7008"]],AUTHORITY["EPSG","6267"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4267"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26711"]] + 4.4072000000000000e+05, 6.0000000000000000e+01, 0.0000000000000000e+00, 3.7513200000000000e+06, 0.0000000000000000e+00, -6.0000000000000000e+01 + + Gray + + + + + ../byte.tif + 1 + + + + + + + 1 + + + + + + diff --git a/autotest/gcore/gcps2geotransform.py b/autotest/gcore/gcps2geotransform.py index 3ef4567210c0..917c42df8d5e 100755 --- a/autotest/gcore/gcps2geotransform.py +++ b/autotest/gcore/gcps2geotransform.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2013 Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gcore/gdal_stats.py b/autotest/gcore/gdal_stats.py index 95137a355879..369eac85dab6 100755 --- a/autotest/gcore/gdal_stats.py +++ b/autotest/gcore/gdal_stats.py @@ -180,6 +180,10 @@ def test_stats_nan_3(): # and complex source nodata (#3576) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_stats_nan_4(): ds = gdal.Open("data/nan32_nodata.vrt") @@ -197,6 +201,10 @@ def test_stats_nan_4(): # and complex source nodata (nan must be translated to 0 then) (#3576) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_stats_nan_5(): ds = gdal.Open("data/nan32_nodata_nan_to_zero.vrt") @@ -213,6 +221,10 @@ def test_stats_nan_5(): # Test reading a warped VRT with nan as src nodata and dest nodata (#3576) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_stats_nan_6(): ds = gdal.Open("data/nan32_nodata_warp.vrt") @@ -229,6 +241,10 @@ def test_stats_nan_6(): # Test reading a warped VRT with nan as src nodata and 0 as dest nodata (#3576) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_stats_nan_7(): ds = gdal.Open("data/nan32_nodata_warp_nan_to_zero.vrt") @@ -245,6 +261,10 @@ def test_stats_nan_7(): # Test reading a warped VRT with zero as src nodata and nan as dest nodata (#3576) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_stats_nan_8(): ds = gdal.Open("data/nan32_nodata_warp_zero_to_nan.vrt") @@ -266,6 +286,7 @@ def stats_nodata_inf_progress_cbk(value, string, extra): extra[0] = value +@pytest.mark.require_driver("HFA") def test_stats_nodata_inf(): ds = gdal.GetDriverByName("HFA").Create( diff --git a/autotest/gcore/geoloc.py b/autotest/gcore/geoloc.py index d27be4319703..8bdd0cde4d6e 100755 --- a/autotest/gcore/geoloc.py +++ b/autotest/gcore/geoloc.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -41,6 +25,10 @@ # Verify warped result. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_geoloc_1(): tst = gdaltest.GDALTest("VRT", "warpsst.vrt", 1, 63034) diff --git a/autotest/gcore/hdf4multidim.py b/autotest/gcore/hdf4multidim.py index 71070df1eb62..c8185b49432d 100644 --- a/autotest/gcore/hdf4multidim.py +++ b/autotest/gcore/hdf4multidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gcore/hfa_read.py b/autotest/gcore/hfa_read.py index a2b559dd95b0..46b5c6a4d29b 100755 --- a/autotest/gcore/hfa_read.py +++ b/autotest/gcore/hfa_read.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2003, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/hfa_rfc40.py b/autotest/gcore/hfa_rfc40.py index 64ed11197c19..452fba977b2a 100755 --- a/autotest/gcore/hfa_rfc40.py +++ b/autotest/gcore/hfa_rfc40.py @@ -11,30 +11,17 @@ ############################################################################### # Copyright (c) 2013, Sam Gillingham # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest from osgeo import gdal -pytestmark = pytest.mark.random_order(disabled=True) +pytestmark = [ + pytest.mark.random_order(disabled=True), + pytest.mark.require_driver("HFA"), +] # All tests will be skipped if numpy is unavailable. np = pytest.importorskip("numpy") diff --git a/autotest/gcore/hfa_srs.py b/autotest/gcore/hfa_srs.py index f560996ed906..64b00d85ff2b 100755 --- a/autotest/gcore/hfa_srs.py +++ b/autotest/gcore/hfa_srs.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -33,6 +17,8 @@ from osgeo import gdal, osr +pytestmark = pytest.mark.require_driver("HFA") + ############################################################################### # Write a HFA/Imagine and read it back to check its SRS crs_list = [ diff --git a/autotest/gcore/hfa_write.py b/autotest/gcore/hfa_write.py index da0ea139c08a..5ab4cc6ee4db 100755 --- a/autotest/gcore/hfa_write.py +++ b/autotest/gcore/hfa_write.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -39,6 +23,8 @@ from osgeo import gdal, osr +pytestmark = pytest.mark.require_driver("HFA") + ############################################################################### # test that we can write a small file with a custom layer name. @@ -298,23 +284,30 @@ def test_hfa_use_rrd(): @pytest.mark.require_driver("BMP") -def test_hfa_update_existing_aux_overviews(): +def test_hfa_update_existing_aux_overviews(tmp_path): + + tmp_filename = str(tmp_path / "hfa_update_existing_aux_overviews.bmp") with gdal.config_option("USE_RRD", "YES"): - ds = gdal.GetDriverByName("BMP").Create( - "tmp/hfa_update_existing_aux_overviews.bmp", 100, 100, 1 - ) + ds = gdal.GetDriverByName("BMP").Create(tmp_filename, 100, 100, 1) ds.GetRasterBand(1).Fill(255) ds = None # Create overviews - ds = gdal.Open("tmp/hfa_update_existing_aux_overviews.bmp") - ds.BuildOverviews("NEAR", overviewlist=[2, 4]) + ds = gdal.Open(tmp_filename) + with gdaltest.disable_exceptions(): + ret = ds.BuildOverviews("NEAR", overviewlist=[2, 4]) + if ( + gdal.GetLastErrorMsg() + == "This build does not support creating .aux overviews" + ): + pytest.skip(gdal.GetLastErrorMsg()) + assert ret == 0 ds = None # Save overviews checksum - ds = gdal.Open("tmp/hfa_update_existing_aux_overviews.bmp") + ds = gdal.Open(tmp_filename) cs_ovr0 = ds.GetRasterBand(1).GetOverview(0).Checksum() cs_ovr1 = ds.GetRasterBand(1).GetOverview(1).Checksum() @@ -322,7 +315,7 @@ def test_hfa_update_existing_aux_overviews(): ds.BuildOverviews("NEAR", overviewlist=[2, 4]) ds = None - ds = gdal.Open("tmp/hfa_update_existing_aux_overviews.bmp") + ds = gdal.Open(tmp_filename) # Check overviews checksum new_cs_ovr0 = ds.GetRasterBand(1).GetOverview(0).Checksum() new_cs_ovr1 = ds.GetRasterBand(1).GetOverview(1).Checksum() @@ -336,7 +329,7 @@ def test_hfa_update_existing_aux_overviews(): ds.BuildOverviews("NEAR", overviewlist=[2, 4]) ds = None - ds = gdal.Open("tmp/hfa_update_existing_aux_overviews.bmp") + ds = gdal.Open(tmp_filename) # Check overviews checksum new_cs_ovr0 = ds.GetRasterBand(1).GetOverview(0).Checksum() new_cs_ovr1 = ds.GetRasterBand(1).GetOverview(1).Checksum() @@ -349,7 +342,7 @@ def test_hfa_update_existing_aux_overviews(): ds.BuildOverviews("NEAR", overviewlist=[8]) ds = None - ds = gdal.Open("tmp/hfa_update_existing_aux_overviews.bmp") + ds = gdal.Open(tmp_filename) # Check overviews checksum new_cs_ovr0 = ds.GetRasterBand(1).GetOverview(0).Checksum() new_cs_ovr1 = ds.GetRasterBand(1).GetOverview(1).Checksum() @@ -359,7 +352,7 @@ def test_hfa_update_existing_aux_overviews(): pytest.fail() ds = None - gdal.GetDriverByName("BMP").Delete("tmp/hfa_update_existing_aux_overviews.bmp") + gdal.GetDriverByName("BMP").Delete(tmp_filename) ############################################################################### diff --git a/autotest/gcore/histogram.py b/autotest/gcore/histogram.py index 0d9a0be16074..6ec38dec0456 100755 --- a/autotest/gcore/histogram.py +++ b/autotest/gcore/histogram.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import math diff --git a/autotest/gcore/identify.py b/autotest/gcore/identify.py index 7c12ca1db8b1..f6b6d555c205 100755 --- a/autotest/gcore/identify.py +++ b/autotest/gcore/identify.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/interpolateatpoint.py b/autotest/gcore/interpolateatpoint.py index 3dffd4c8b3f1..767a144e54dd 100755 --- a/autotest/gcore/interpolateatpoint.py +++ b/autotest/gcore/interpolateatpoint.py @@ -302,6 +302,10 @@ def test_interpolateatpoint_complex_float(): assert res == pytest.approx((34.433130 - 36.741504j), 1e-4) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_interpolateatpoint_big_complex(): # The purpose of this test is to check that the algorithm implementation # works for bigger values above the first block of 64x64 pixels. diff --git a/autotest/gcore/mask.py b/autotest/gcore/mask.py index 180521e11b65..9e53178fedc9 100755 --- a/autotest/gcore/mask.py +++ b/autotest/gcore/mask.py @@ -10,23 +10,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -72,6 +56,10 @@ def test_mask_1(): # Verify the checksum and flags for "nodata" case. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_mask_2(): ds = gdal.Open("data/byte.vrt") diff --git a/autotest/gcore/minixml.py b/autotest/gcore/minixml.py index d61dc4b03a00..449506553d8b 100755 --- a/autotest/gcore/minixml.py +++ b/autotest/gcore/minixml.py @@ -10,23 +10,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2009-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/misc.py b/autotest/gcore/misc.py index 77f6d6670075..2c4b1d70c1a3 100755 --- a/autotest/gcore/misc.py +++ b/autotest/gcore/misc.py @@ -10,25 +10,10 @@ ############################################################################### # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import datetime import os import shutil @@ -269,7 +254,7 @@ def test_misc_5(): ############################################################################### -class misc_6_interrupt_callback_class(object): +class misc_6_interrupt_callback_class: def __init__(self): pass @@ -297,62 +282,20 @@ def misc_6_internal(datatype, nBands, setDriversDone): drv = gdal.GetDriver(i) md = drv.GetMetadata() if ("DCAP_CREATECOPY" in md or "DCAP_CREATE" in md) and "DCAP_RASTER" in md: - # print ('drv = %s, nBands = %d, datatype = %s' % (drv.ShortName, nBands, gdal.GetDataTypeName(datatype))) - - skip = False - # FIXME: A few cases that crashes and should be investigated - if drv.ShortName == "JPEG2000": - if (nBands == 2 or nBands >= 5) or not ( - datatype == gdal.GDT_Byte - or datatype == gdal.GDT_Int16 - or datatype == gdal.GDT_UInt16 - ): - skip = True - - if skip is False: - dirname = "tmp/tmp/tmp_%s_%d_%s" % ( - drv.ShortName, - nBands, - gdal.GetDataTypeName(datatype), - ) - try: - os.mkdir(dirname) - except OSError: - try: - os.stat(dirname) - # Hum the directory already exists... Not expected, but let's try to go on - except OSError: - reason = ( - "Cannot create %s before drv = %s, nBands = %d, datatype = %s" - % ( - dirname, - drv.ShortName, - nBands, - gdal.GetDataTypeName(datatype), - ) - ) - pytest.fail(reason) - - filename = get_filename(drv, dirname) - - dst_ds = drv.CreateCopy(filename, ds) - has_succeeded = dst_ds is not None - if dst_ds: - # check that domain == None doesn't crash - dst_ds.GetMetadata(None) - dst_ds.GetMetadataItem("", None) - dst_ds = None - - size = 0 - stat = gdal.VSIStatL(filename) - if stat is not None: - size = stat.size - + dirname = "tmp/tmp/tmp_%s_%d_%s" % ( + drv.ShortName, + nBands, + gdal.GetDataTypeName(datatype), + ) + try: + os.mkdir(dirname) + except OSError: try: - shutil.rmtree(dirname) + os.stat(dirname) + # Hum the directory already exists... Not expected, but let's try to go on except OSError: reason = ( - "Cannot remove %s after drv = %s, nBands = %d, datatype = %s" + "Cannot create %s before drv = %s, nBands = %d, datatype = %s" % ( dirname, drv.ShortName, @@ -362,114 +305,142 @@ def misc_6_internal(datatype, nBands, setDriversDone): ) pytest.fail(reason) - if has_succeeded and drv.ShortName not in setDriversDone and nBands > 0: - setDriversDone.add(drv.ShortName) + filename = get_filename(drv, dirname) - # The first list of drivers fail to detect short writing - # The second one is because they are verbose in stderr - if ( - "DCAP_VIRTUALIO" in md - and size != 0 - and drv.ShortName - not in [ - "JPEG2000", - "KMLSUPEROVERLAY", - "HF2", - "ZMap", - "DDS", - "TileDB", - ] - and drv.ShortName not in ["GIF", "JP2ECW", "JP2Lura"] - ): + dst_ds = drv.CreateCopy(filename, ds) + has_succeeded = dst_ds is not None + if dst_ds: + # check that domain == None doesn't crash + dst_ds.GetMetadata(None) + dst_ds.GetMetadataItem("", None) + dst_ds = None - for j in range(10): - truncated_size = (size * j) / 10 - vsimem_filename = ( - "/vsimem/test_truncate/||maxlength=%d||" - % truncated_size - ) + get_filename(drv, "")[1:] - # print('drv = %s, nBands = %d, datatype = %s, truncated_size = %d' % (drv.ShortName, nBands, gdal.GetDataTypeName(datatype), truncated_size)) - dst_ds = drv.CreateCopy(vsimem_filename, ds) - error_detected = False - if dst_ds is None: - error_detected = True - else: - gdal.ErrorReset() - dst_ds = None - if gdal.GetLastErrorMsg() != "": - error_detected = True - if not error_detected: - msg = ( - "write error not detected with with drv = %s, nBands = %d, datatype = %s, truncated_size = %d" - % ( - drv.ShortName, - nBands, - gdal.GetDataTypeName(datatype), - truncated_size, - ) - ) - print(msg) + size = 0 + stat = gdal.VSIStatL(filename) + if stat is not None: + size = stat.size - fl = gdal.ReadDirRecursive("/vsimem/test_truncate") - if fl is not None: - for myf in fl: - gdal.Unlink("/vsimem/test_truncate/" + myf) - fl = gdal.ReadDirRecursive("/vsimem/test_truncate") - if fl is not None: - print(fl) - - if drv.ShortName not in [ - "ECW", - "JP2ECW", - "VRT", - "XPM", + try: + shutil.rmtree(dirname) + except OSError: + reason = ( + "Cannot remove %s after drv = %s, nBands = %d, datatype = %s" + % ( + dirname, + drv.ShortName, + nBands, + gdal.GetDataTypeName(datatype), + ) + ) + pytest.fail(reason) + + if has_succeeded and drv.ShortName not in setDriversDone and nBands > 0: + setDriversDone.add(drv.ShortName) + + # The first list of drivers fail to detect short writing + # The second one is because they are verbose in stderr + if ( + "DCAP_VIRTUALIO" in md + and size != 0 + and drv.ShortName + not in [ "JPEG2000", - "FIT", - "RST", - "INGR", - "USGSDEM", "KMLSUPEROVERLAY", - "GMT", - ]: - dst_ds = drv.CreateCopy( - filename, ds, callback=misc_6_interrupt_callback_class().cbk - ) - if dst_ds is not None: - dst_ds = None - - try: - shutil.rmtree(dirname) - except OSError: - pass + "HF2", + "ZMap", + "DDS", + "TileDB", + ] + and drv.ShortName not in ["GIF", "JP2ECW", "JP2Lura"] + ): - pytest.fail( - "interruption did not work with drv = %s, nBands = %d, datatype = %s" + for j in range(10): + truncated_size = (size * j) / 10 + vsimem_filename = ( + "/vsimem/test_truncate/||maxlength=%d||" % truncated_size + ) + get_filename(drv, "")[1:] + # print('drv = %s, nBands = %d, datatype = %s, truncated_size = %d' % (drv.ShortName, nBands, gdal.GetDataTypeName(datatype), truncated_size)) + dst_ds = drv.CreateCopy(vsimem_filename, ds) + error_detected = False + if dst_ds is None: + error_detected = True + else: + gdal.ErrorReset() + dst_ds = None + if gdal.GetLastErrorMsg() != "": + error_detected = True + if not error_detected: + msg = ( + "write error not detected with with drv = %s, nBands = %d, datatype = %s, truncated_size = %d" % ( drv.ShortName, nBands, gdal.GetDataTypeName(datatype), + truncated_size, ) ) + print(msg) + fl = gdal.ReadDirRecursive("/vsimem/test_truncate") + if fl is not None: + for myf in fl: + gdal.Unlink("/vsimem/test_truncate/" + myf) + fl = gdal.ReadDirRecursive("/vsimem/test_truncate") + if fl is not None: + print(fl) + + if drv.ShortName not in [ + "ECW", + "JP2ECW", + "VRT", + "XPM", + "JPEG2000", + "FIT", + "RST", + "INGR", + "USGSDEM", + "KMLSUPEROVERLAY", + "GMT", + ]: + dst_ds = drv.CreateCopy( + filename, ds, callback=misc_6_interrupt_callback_class().cbk + ) + if dst_ds is not None: dst_ds = None try: shutil.rmtree(dirname) except OSError: pass - try: - os.mkdir(dirname) - except OSError: - reason = ( - "Cannot create %s before drv = %s, nBands = %d, datatype = %s" - % ( - dirname, - drv.ShortName, - nBands, - gdal.GetDataTypeName(datatype), - ) + + pytest.fail( + "interruption did not work with drv = %s, nBands = %d, datatype = %s" + % ( + drv.ShortName, + nBands, + gdal.GetDataTypeName(datatype), + ) + ) + + dst_ds = None + + try: + shutil.rmtree(dirname) + except OSError: + pass + try: + os.mkdir(dirname) + except OSError: + reason = ( + "Cannot create %s before drv = %s, nBands = %d, datatype = %s" + % ( + dirname, + drv.ShortName, + nBands, + gdal.GetDataTypeName(datatype), ) - pytest.fail(reason) + ) + pytest.fail(reason) ds = None @@ -751,6 +722,70 @@ def test_misc_13(): assert out_ds is None +############################################################################### +# Test parsing of CPL_DEBUG and CPL_TIMESTAMP + + +@pytest.fixture +def debug_output(): + + messages = [] + + def handle(ecls, ecode, emsg): + messages.append(emsg) + + def log_message(category, message): + messages.clear() + gdal.Debug(category, message) + return messages[0] if messages else None + + log_message.handle = handle + + with gdaltest.error_handler(handle): + yield log_message + + +@pytest.mark.parametrize( + "booleans", + [("YES", "NO"), ("TRUE", "FALSE"), ("ON", "OFF"), ("1", "0")], + ids="_".join, +) +def test_misc_cpl_debug(debug_output, booleans): + + on, off = booleans + + assert debug_output("GDAL", "msg") is None + + with gdal.config_option("CPL_DEBUG", off): + assert debug_output("GDAL", "msg") is None + + with gdal.config_option("CPL_DEBUG", on): + assert debug_output("GDAL", "message") == "GDAL: message" + + with gdal.config_option("CPL_TIMESTAMP", off): + assert debug_output("GDAL", "message") == "GDAL: message" + + with gdal.config_option("CPL_TIMESTAMP", on): + output = debug_output("GDAL", "message") + assert str(datetime.datetime.now().year) in output + assert output.endswith("GDAL: message") + + +def test_misc_cpl_debug_filtering(debug_output): + + with gdal.config_option("CPL_DEBUG", "GDAL"): + assert debug_output("GDAL", "msg") == "GDAL: msg" + assert debug_output("GDAL_WARP", "msg") is None + assert debug_output("", "msg") == ": msg" + + with gdal.config_option("CPL_DEBUG", "GDAL_WARP_TRANSLATE_ETC"): + assert debug_output("GDAL", "msg") == "GDAL: msg" + assert debug_output("TRANSLATE", "msg") == "TRANSLATE: msg" + + with gdal.config_option("CPL_DEBUG", ""): + assert debug_output("GDAL", "msg") == "GDAL: msg" + + ############################################################################### # Test ConfigureLogging() diff --git a/autotest/gcore/multidim.py b/autotest/gcore/multidim.py index c70fd40ad6dc..3c038588aa33 100644 --- a/autotest/gcore/multidim.py +++ b/autotest/gcore/multidim.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/gcore/nodatamaskband.py b/autotest/gcore/nodatamaskband.py index 2a9e253ef00f..3bf93f101f9d 100755 --- a/autotest/gcore/nodatamaskband.py +++ b/autotest/gcore/nodatamaskband.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gcore/numpy_rw.py b/autotest/gcore/numpy_rw.py index d4451ab0dcf7..ac3d388478d9 100755 --- a/autotest/gcore/numpy_rw.py +++ b/autotest/gcore/numpy_rw.py @@ -10,23 +10,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -732,6 +716,10 @@ def test_numpy_rw_18(): # The VRT references a non existing TIF file, but using the proxy pool dataset API (#2837) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_numpy_rw_failure_in_readasarray(): ds = gdal.Open("data/idontexist2.vrt") @@ -964,6 +952,10 @@ def test_numpy_rw_band_read_as_array_error_cases(): # Test that we can get an error (#5374) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_numpy_rw_band_read_as_array_getlasterrormsg(): ds = gdal.Open( diff --git a/autotest/gcore/numpy_rw_multidim.py b/autotest/gcore/numpy_rw_multidim.py index 9e9214448dd6..5b2d558a9467 100755 --- a/autotest/gcore/numpy_rw_multidim.py +++ b/autotest/gcore/numpy_rw_multidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/overviewds.py b/autotest/gcore/overviewds.py index a3a8a11a4540..acb19f34ba01 100755 --- a/autotest/gcore/overviewds.py +++ b/autotest/gcore/overviewds.py @@ -10,28 +10,13 @@ ############################################################################### # Copyright (c) 2014 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil import struct +import gdaltest import pytest from osgeo import gdal @@ -250,6 +235,10 @@ def test_overviewds_4(tmp_path): # Test GEOLOCATION +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_overviewds_5(tmp_path): shutil.copy("data/sstgeo.tif", tmp_path) @@ -296,6 +285,10 @@ def test_overviewds_5(tmp_path): # Test VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_overviewds_6(tmp_path): shutil.copy("data/byte.tif", tmp_path) diff --git a/autotest/gcore/pam.py b/autotest/gcore/pam.py index 0af14cd16b38..110daffaef3f 100755 --- a/autotest/gcore/pam.py +++ b/autotest/gcore/pam.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -175,6 +159,7 @@ def test_pam_5(): # +@pytest.mark.require_driver("HFA") def test_pam_6(): ds = gdal.Open("data/f2r23.tif") diff --git a/autotest/gcore/pamproxydb.py b/autotest/gcore/pamproxydb.py index 0612484cda86..6a791b592882 100755 --- a/autotest/gcore/pamproxydb.py +++ b/autotest/gcore/pamproxydb.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/pixfun.py b/autotest/gcore/pixfun.py index 57fcf99f3fb3..dfb528788134 100755 --- a/autotest/gcore/pixfun.py +++ b/autotest/gcore/pixfun.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2014, Antonio Valentino # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -35,6 +19,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + # All tests will be skipped if numpy is unavailable. numpy = pytest.importorskip("numpy") diff --git a/autotest/gcore/pnm_read.py b/autotest/gcore/pnm_read.py index fdbddaaff4f4..c2e0570ba4a4 100755 --- a/autotest/gcore/pnm_read.py +++ b/autotest/gcore/pnm_read.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2003, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gcore/rasterio.py b/autotest/gcore/rasterio.py index cee967b15724..c0e8d3ee95ed 100755 --- a/autotest/gcore/rasterio.py +++ b/autotest/gcore/rasterio.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -38,14 +22,6 @@ from osgeo import gdal - -############################################################################### -@pytest.fixture(autouse=True, scope="module") -def module_disable_exceptions(): - with gdaltest.disable_exceptions(): - yield - - ############################################################################### # Test writing a 1x1 buffer to a 10x6 raster and read it back @@ -233,6 +209,7 @@ def test_rasterio_4(): # Test error cases of ReadRaster() +@gdaltest.disable_exceptions() def test_rasterio_5(): ds = gdal.Open("data/byte.tif") @@ -300,6 +277,7 @@ def test_rasterio_5(): # Test error cases of WriteRaster() +@gdaltest.disable_exceptions() def test_rasterio_6(): ds = gdal.GetDriverByName("MEM").Create("", 2, 2) @@ -773,6 +751,7 @@ def test_rasterio_overview_subpixel_resampling(): # Test error when getting a block +@gdaltest.disable_exceptions() def test_rasterio_10(): ds = gdal.Open("data/byte_truncated.tif") @@ -884,29 +863,153 @@ def test_rasterio_12(): # Test cubic resampling with masking -def test_rasterio_13(): +@pytest.mark.parametrize( + "dt", + [ + "Byte", + "Int8", + "Int16", + "UInt16", + "Int32", + "UInt32", + "Int64", + "UInt64", + "Float32", + "Float64", + ], +) +def test_rasterio_13(dt): numpy = pytest.importorskip("numpy") - for dt in [gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_UInt32]: + dt = gdal.GetDataTypeByName(dt) + mem_ds = gdal.GetDriverByName("MEM").Create("", 4, 3, 1, dt) + mem_ds.GetRasterBand(1).SetNoDataValue(0) + if dt == gdal.GDT_Int8: + x = (1 << 7) - 1 + elif dt == gdal.GDT_Byte: + x = (1 << 8) - 1 + elif dt == gdal.GDT_Int16: + x = (1 << 15) - 1 + elif dt == gdal.GDT_UInt16: + x = (1 << 16) - 1 + elif dt == gdal.GDT_Int32: + x = (1 << 31) - 1 + elif dt == gdal.GDT_UInt32: + x = (1 << 32) - 1 + elif dt == gdal.GDT_Int64: + x = (1 << 63) - 1 + elif dt == gdal.GDT_UInt64: + x = (1 << 64) - 2048 + elif dt == gdal.GDT_Float32: + x = 1.5 + else: + x = 1.23456 + mem_ds.GetRasterBand(1).WriteArray( + numpy.array([[0, 0, 0, 0], [0, x, 0, 0], [0, 0, 0, 0]]) + ) - mem_ds = gdal.GetDriverByName("MEM").Create("", 4, 3, 1, dt) - mem_ds.GetRasterBand(1).SetNoDataValue(0) - mem_ds.GetRasterBand(1).WriteArray( - numpy.array([[0, 0, 0, 0], [0, 255, 0, 0], [0, 0, 0, 0]]) - ) + ar_ds = mem_ds.ReadAsArray( + 0, 0, 4, 3, buf_xsize=8, buf_ysize=3, resample_alg=gdal.GRIORA_Cubic + ) - ar_ds = mem_ds.ReadAsArray( - 0, 0, 4, 3, buf_xsize=8, buf_ysize=3, resample_alg=gdal.GRIORA_Cubic - ) + expected_ar = numpy.array( + [ + [0, 0, 0, 0, 0, 0, 0, 0], + [0, x, x, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + ] + ) + assert numpy.array_equal(ar_ds, expected_ar) - expected_ar = numpy.array( - [ - [0, 0, 0, 0, 0, 0, 0, 0], - [0, 255, 255, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0], - ] - ) - assert numpy.array_equal(ar_ds, expected_ar), (ar_ds, dt) + +############################################################################### +# Test nearest and mode resampling + + +@pytest.mark.parametrize( + "dt", + [ + "Byte", + "Int8", + "Int16", + "UInt16", + "Int32", + "UInt32", + "Int64", + "UInt64", + "Float32", + "Float64", + "CInt16", + "CInt32", + "CFloat32", + "CFloat64", + ], +) +@pytest.mark.parametrize( + "resample_alg", [gdal.GRIORA_NearestNeighbour, gdal.GRIORA_Mode] +) +@pytest.mark.parametrize("use_nan", [True, False]) +def test_rasterio_nearest_or_mode(dt, resample_alg, use_nan): + numpy = pytest.importorskip("numpy") + gdal_array = pytest.importorskip("osgeo.gdal_array") + + dt = gdal.GetDataTypeByName(dt) + mem_ds = gdal.GetDriverByName("MEM").Create("", 4, 4, 1, dt) + if dt == gdal.GDT_Int8: + x = (1 << 7) - 1 + elif dt == gdal.GDT_Byte: + x = (1 << 8) - 1 + elif dt == gdal.GDT_Int16 or dt == gdal.GDT_CInt16: + x = (1 << 15) - 1 + elif dt == gdal.GDT_UInt16: + x = (1 << 16) - 1 + elif dt == gdal.GDT_Int32 or dt == gdal.GDT_CInt32: + x = (1 << 31) - 1 + elif dt == gdal.GDT_UInt32: + x = (1 << 32) - 1 + elif dt == gdal.GDT_Int64: + x = (1 << 63) - 1 + elif dt == gdal.GDT_UInt64: + x = (1 << 64) - 1 + elif dt == gdal.GDT_Float32 or dt == gdal.GDT_CFloat32: + x = float("nan") if use_nan else 1.5 + else: + x = float("nan") if use_nan else 1.234567890123 + + if gdal.DataTypeIsComplex(dt): + val = complex(x, x) + else: + val = x + + dtype = gdal_array.flip_code(dt) + mem_ds.GetRasterBand(1).WriteArray(numpy.full((4, 4), val, dtype=dtype)) + + ar_ds = mem_ds.ReadAsArray( + 0, 0, 4, 4, buf_xsize=1, buf_ysize=1, resample_alg=resample_alg + ) + + expected_ar = numpy.array([[val]]).astype(dtype) + if math.isnan(x): + if gdal.DataTypeIsComplex(dt): + assert math.isnan(ar_ds[0][0].real) and math.isnan(ar_ds[0][0].imag) + else: + assert math.isnan(ar_ds[0][0]) + else: + assert numpy.array_equal(ar_ds, expected_ar) + + resample_alg_mapping = { + gdal.GRIORA_NearestNeighbour: "NEAR", + gdal.GRIORA_Mode: "MODE", + } + mem_ds.BuildOverviews(resample_alg_mapping[resample_alg], [4]) + ar_ds = mem_ds.GetRasterBand(1).GetOverview(0).ReadAsArray() + if math.isnan(x): + if gdal.DataTypeIsComplex(dt): + assert math.isnan(ar_ds[0][0].real) and math.isnan(ar_ds[0][0].imag) + else: + assert math.isnan(ar_ds[0][0]) + else: + assert numpy.array_equal(ar_ds, expected_ar) ############################################################################### @@ -1323,6 +1426,7 @@ def test_rasterio_dataset_readarray_cint16(): assert got[1] == numpy.array([[3 + 4j]]) +@gdaltest.disable_exceptions() def test_rasterio_rasterband_write_on_readonly(): ds = gdal.Open("data/byte.tif") @@ -1332,6 +1436,7 @@ def test_rasterio_rasterband_write_on_readonly(): assert err != 0 +@gdaltest.disable_exceptions() def test_rasterio_dataset_write_on_readonly(): ds = gdal.Open("data/byte.tif") @@ -2904,6 +3009,7 @@ def test_rasterio_writeraster_from_memoryview(): # Test ReadRaster() in an existing buffer +@gdaltest.disable_exceptions() def test_rasterio_readraster_in_existing_buffer(): ds = gdal.GetDriverByName("MEM").Create("", 2, 1) @@ -2940,6 +3046,7 @@ def test_rasterio_readraster_in_existing_buffer(): # Test ReadBlock() in an existing buffer +@gdaltest.disable_exceptions() def test_rasterio_readblock_in_existing_buffer(): ds = gdal.GetDriverByName("MEM").Create("", 2, 1) @@ -2966,6 +3073,7 @@ def test_rasterio_readblock_in_existing_buffer(): # Test ReadRaster() in an existing buffer and alignment issues +@gdaltest.disable_exceptions() @pytest.mark.parametrize( "datatype", [ @@ -3194,11 +3302,11 @@ def test_rasterio_overview_selection(): assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 101, 101)[0] == 1 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 100, 100)[0] == 1 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 99, 99)[0] == 1 - assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 60, 60)[0] == 1 + assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 60, 60)[0] == 2 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 59, 59)[0] == 2 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 50, 50)[0] == 2 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 49, 49)[0] == 2 - assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 30, 30)[0] == 2 + assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 30, 30)[0] == 3 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 29, 29)[0] == 3 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 25, 25)[0] == 3 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 24, 24)[0] == 3 @@ -3282,3 +3390,18 @@ def test_rasterio_overview_selection(): assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 29, 29)[0] == 2 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 25, 25)[0] == 3 assert ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 24, 24)[0] == 3 + + +############################################################################### +# Check robustness to GDT_Unknown + + +def test_rasterio_gdt_unknown(): + + with gdal.GetDriverByName("MEM").Create("", 1, 1) as ds: + # Caught at the SWIG level + with pytest.raises(Exception, match="Illegal value for data type"): + ds.ReadRaster(buf_type=gdal.GDT_Unknown) + # Caught at the SWIG level + with pytest.raises(Exception, match="Illegal value for data type"): + ds.GetRasterBand(1).ReadRaster(buf_type=gdal.GDT_Unknown) diff --git a/autotest/gcore/rat.py b/autotest/gcore/rat.py index 3128fc4fbedd..d6ec55609915 100755 --- a/autotest/gcore/rat.py +++ b/autotest/gcore/rat.py @@ -11,23 +11,7 @@ # Copyright (c) 2009, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gcore/relationship.py b/autotest/gcore/relationship.py index 60d32f24085e..15906ad4dd0e 100755 --- a/autotest/gcore/relationship.py +++ b/autotest/gcore/relationship.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, Nyall Dawson # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest @@ -35,7 +19,7 @@ def test_gdal_relationship(): - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.Relationship(None, None, None, gdal.GRC_ONE_TO_ONE) relationship = gdal.Relationship( diff --git a/autotest/gcore/rfc30.py b/autotest/gcore/rfc30.py index bbafb243a1d3..12c9324930f7 100755 --- a/autotest/gcore/rfc30.py +++ b/autotest/gcore/rfc30.py @@ -10,23 +10,7 @@ # Copyright (c) 2010 Frank Warmerdam # Copyright (c) 2010-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import urllib.parse diff --git a/autotest/gcore/test_driver_metadata.py b/autotest/gcore/test_driver_metadata.py index 81ba941c84da..7f1bee6eb8a1 100644 --- a/autotest/gcore/test_driver_metadata.py +++ b/autotest/gcore/test_driver_metadata.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020, Rene Buffat # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -392,6 +376,13 @@ ) +@pytest.mark.parametrize("driver_name", all_driver_names) +def test_metadata_has_long_name(driver_name): + + driver = gdal.GetDriverByName(driver_name) + assert driver.GetMetadataItem(gdal.DMD_LONGNAME) is not None + + @pytest.mark.parametrize("driver_name", all_driver_names) def test_metadata_dcap_yes(driver_name): """Test that the only value of DCAP_ elements is YES""" diff --git a/autotest/gcore/test_gdal_fsspec.py b/autotest/gcore/test_gdal_fsspec.py new file mode 100644 index 000000000000..38deb8da07be --- /dev/null +++ b/autotest/gcore/test_gdal_fsspec.py @@ -0,0 +1,225 @@ +#!/usr/bin/env pytest +# -*- coding: utf-8 -*- +############################################################################### +# Project: GDAL/OGR Test Suite +# Purpose: Test gdal_fsspec module +# Author: Even Rouault +# +############################################################################### +# Copyright (c) 20124, Even Rouault +# +# SPDX-License-Identifier: MIT +############################################################################### + +import pytest + +from osgeo import gdal + +fsspec = pytest.importorskip("fsspec") +pytest.importorskip("fsspec.spec") + +from osgeo import gdal_fsspec # NOQA + + +def test_gdal_fsspec_open_read(): + + with fsspec.open("gdalvsi://data/byte.tif") as f: + assert len(f.read()) == gdal.VSIStatL("data/byte.tif").size + + +def test_gdal_fsspec_info_file(): + + fs = fsspec.filesystem("gdalvsi") + info = fs.info("data/byte.tif") + assert "mtime" in info + del info["mtime"] + assert (info["mode"] & 32768) != 0 + del info["mode"] + assert info == { + "name": "data/byte.tif", + "size": 736, + "type": "file", + } + + +def test_gdal_fsspec_info_dir(): + + fs = fsspec.filesystem("gdalvsi") + info = fs.info("data") + assert (info["mode"] & 16384) != 0 + del info["mode"] + assert info == { + "name": "data", + "size": 0, + "type": "directory", + } + + +def test_gdal_fsspec_info_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.info("/i/do/not/exist") + + +def test_gdal_fsspec_ls(): + + fs = fsspec.filesystem("gdalvsi") + ret = fs.ls("data") + assert len(ret) > 2 + item_of_interest = None + for item in ret: + if item["name"] == "data/byte.tif": + item_of_interest = item + break + assert item_of_interest + assert "mtime" in item_of_interest + del item_of_interest["mtime"] + assert item_of_interest == { + "name": "data/byte.tif", + "size": 736, + "type": "file", + } + + +def test_gdal_fsspec_ls_file(): + + fs = fsspec.filesystem("gdalvsi") + ret = fs.ls("data/byte.tif") + assert ret == ["data/byte.tif"] + + +def test_gdal_fsspec_ls_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.ls("gdalvsi://i/do/not/exist") + + +def test_gdal_fsspec_modified(): + + fs = fsspec.filesystem("gdalvsi") + modified = fs.modified("data/byte.tif") + assert modified is not None + import datetime + + assert isinstance(modified, datetime.datetime) + + +def test_gdal_fsspec_modified_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.modified("gdalvsi://i/do/not/exist") + + +def test_gdal_fsspec_rm(): + + with fsspec.open("gdalvsi:///vsimem/foo.bin", "wb") as f: + f.write(b"""bar""") + fs = fsspec.filesystem("gdalvsi") + fs.info("/vsimem/foo.bin") + fs.rm("/vsimem/foo.bin") + with pytest.raises(FileNotFoundError): + fs.info("/vsimem/foo.bin") + + +def test_gdal_fsspec_rm_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.rm("/vsimem/foo.bin") + + +def test_gdal_fsspec_copy(): + + with fsspec.open("gdalvsi:///vsimem/foo.bin", "wb") as f: + f.write(b"""bar""") + fs = fsspec.filesystem("gdalvsi") + fs.copy("/vsimem/foo.bin", "/vsimem/bar.bin") + assert fs.info("/vsimem/bar.bin")["size"] == 3 + assert fs.info("/vsimem/foo.bin")["size"] == 3 + fs.rm("/vsimem/foo.bin") + fs.rm("/vsimem/bar.bin") + + +def test_gdal_fsspec_copy_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.copy("/vsimem/foo.bin", "/vsimem/bar.bin") + + +def test_gdal_fsspec_mv(): + + with fsspec.open("gdalvsi:///vsimem/foo.bin", "wb") as f: + f.write(b"""bar""") + fs = fsspec.filesystem("gdalvsi") + fs.mv("/vsimem/foo.bin", "/vsimem/bar.bin") + assert fs.info("/vsimem/bar.bin")["size"] == 3 + with pytest.raises(FileNotFoundError): + fs.info("/vsimem/foo.bin") + fs.rm("/vsimem/bar.bin") + + +def test_gdal_fsspec_mv_error(): + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(FileNotFoundError): + fs.mv("/vsimem/foo.bin", "/bar.bin") + + +def test_gdal_fsspec_mkdir(tmp_path): + + fs = fsspec.filesystem("gdalvsi") + + my_path = str(tmp_path) + "/my_dir" + + fs.mkdir(my_path) + assert fs.info(my_path)["type"] == "directory" + with pytest.raises(FileExistsError): + fs.mkdir(my_path) + fs.rmdir(my_path) + + fs.mkdir(my_path + "/my_subdir") + assert fs.info(my_path)["type"] == "directory" + assert fs.info(my_path + "/my_subdir")["type"] == "directory" + fs.rmdir(my_path + "/my_subdir") + fs.rmdir(my_path) + with pytest.raises(FileNotFoundError): + fs.info(my_path) + + fs = fsspec.filesystem("gdalvsi") + with pytest.raises(Exception): + fs.mkdir(my_path + "/my_subdir", create_parents=False) + with pytest.raises(FileNotFoundError): + fs.info(my_path) + + +def test_gdal_fsspec_makedirs(tmp_path): + + fs = fsspec.filesystem("gdalvsi") + + my_path = str(tmp_path) + "/my_dir" + fs.makedirs(my_path) + assert fs.info(my_path)["type"] == "directory" + with pytest.raises(FileExistsError): + fs.makedirs(my_path) + fs.makedirs(my_path, exist_ok=True) + fs.rmdir(my_path) + + +def test_gdal_fsspec_usable_by_pyarrow_dataset(tmp_vsimem): + + ds = pytest.importorskip("pyarrow.dataset") + + tmp_vsimem_file = str(tmp_vsimem / "tmp.parquet") + gdal.FileFromMemBuffer( + tmp_vsimem_file, open("../ogr/data/parquet/test.parquet", "rb").read() + ) + + fs_vsimem = fsspec.filesystem("gdalvsi") + + assert ds.dataset(tmp_vsimem_file, filesystem=fs_vsimem) is not None + + assert ds.dataset(str(tmp_vsimem), filesystem=fs_vsimem) is not None diff --git a/autotest/gcore/testnonboundtoswig.py b/autotest/gcore/testnonboundtoswig.py index 8979d26f4512..53f7c0c53953 100755 --- a/autotest/gcore/testnonboundtoswig.py +++ b/autotest/gcore/testnonboundtoswig.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ctypes @@ -291,6 +275,10 @@ def my_pyDerivedPixelFunc( return 0 +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_testnonboundtoswig_VRTDerivedBands(): DerivedPixelFuncType = ctypes.CFUNCTYPE( diff --git a/autotest/gcore/thread_test.py b/autotest/gcore/thread_test.py index 9fe563757aae..fb2f32c3a776 100755 --- a/autotest/gcore/thread_test.py +++ b/autotest/gcore/thread_test.py @@ -10,25 +10,10 @@ ############################################################################### # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import shutil import threading import gdaltest @@ -75,3 +60,540 @@ def test_thread_test_1(): ret = False assert ret + + +def launch_threads(get_band, expected_cs, on_mask_band=False): + res = [True] + + def verify_checksum(): + for i in range(1000): + got_cs = get_band().Checksum() + if got_cs != expected_cs: + res[0] = False + assert False, (got_cs, expected_cs) + + threads = [threading.Thread(target=verify_checksum) for i in range(2)] + for t in threads: + t.start() + for t in threads: + t.join() + assert res[0] + + +def test_thread_safe_open(): + + ds = gdal.OpenEx("data/byte.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE) + assert ds.IsThreadSafe(gdal.OF_RASTER) + assert not ds.IsThreadSafe(gdal.OF_RASTER | gdal.OF_UPDATE) + + def get_band(): + return ds.GetRasterBand(1) + + launch_threads(get_band, 4672) + + # Check that GetThreadSafeDataset() on an already thread-safe dataset + # return itself. + ref_count_before = ds.GetRefCount() + thread_safe_ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + assert ds.GetRefCount() == ref_count_before + 1 + assert thread_safe_ds.GetRefCount() == ref_count_before + 1 + del thread_safe_ds + assert ds.GetRefCount() == ref_count_before + + +def test_thread_safe_create(): + + ds = gdal.OpenEx("data/byte.tif", gdal.OF_RASTER) + assert not ds.IsThreadSafe(gdal.OF_RASTER) + assert ds.GetRefCount() == 1 + thread_safe_ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + assert thread_safe_ds.IsThreadSafe(gdal.OF_RASTER) + assert ds.GetRefCount() == 2 + del ds + + def get_band(): + return thread_safe_ds.GetRasterBand(1) + + launch_threads(get_band, 4672) + + +def test_thread_safe_create_close_src_ds(): + + ds = gdal.OpenEx("data/byte.tif", gdal.OF_RASTER) + thread_safe_ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + ds.Close() + with pytest.raises(Exception): + thread_safe_ds.RasterCount + + +def test_thread_safe_src_cannot_be_reopened(tmp_vsimem): + + tmpfilename = str(tmp_vsimem / "byte.tif") + gdal.Translate(tmpfilename, "data/byte.tif") + + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.Unlink(tmpfilename) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + +@pytest.mark.parametrize( + "flag", [gdal.OF_UPDATE, gdal.OF_VECTOR, gdal.OF_MULTIDIM_RASTER, gdal.OF_GNM] +) +def test_thread_safe_incompatible_open_flags(flag): + with pytest.raises(Exception, match="mutually exclusive"): + gdal.OpenEx("data/byte.tif", gdal.OF_THREAD_SAFE | flag) + + +def test_thread_safe_src_alter_after_opening(tmp_vsimem): + + tmpfilename = str(tmp_vsimem / "byte.tif") + + gdal.Translate(tmpfilename, "data/byte.tif") + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.GetDriverByName("GTiff").Create( + tmpfilename, ds.RasterXSize + 1, ds.RasterYSize, ds.RasterCount + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + gdal.Translate(tmpfilename, "data/byte.tif") + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.GetDriverByName("GTiff").Create( + tmpfilename, ds.RasterXSize, ds.RasterYSize + 1, ds.RasterCount + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + gdal.Translate(tmpfilename, "data/byte.tif") + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.GetDriverByName("GTiff").Create( + tmpfilename, ds.RasterXSize, ds.RasterYSize, ds.RasterCount + 1 + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + gdal.Translate(tmpfilename, "data/byte.tif") + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.GetDriverByName("GTiff").Create( + tmpfilename, ds.RasterXSize, ds.RasterYSize, ds.RasterCount, gdal.GDT_Int16 + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + gdal.Translate(tmpfilename, "data/byte.tif") + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + gdal.GetDriverByName("GTiff").Create( + tmpfilename, + ds.RasterXSize, + ds.RasterYSize, + ds.RasterCount, + options=["TILED=YES"], + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).Checksum() + + with gdal.Translate(tmpfilename, "data/byte.tif") as ds: + ds.BuildOverviews("NEAR", [2]) + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + ds.GetRasterBand(1).GetOverviewCount() + gdal.GetDriverByName("GTiff").Create( + tmpfilename, ds.RasterXSize, ds.RasterYSize, ds.RasterCount + ) + with pytest.raises(Exception): + ds.GetRasterBand(1).GetOverview(0).Checksum() + + +def test_thread_safe_mask_band(): + + with gdal.Open("data/stefan_full_rgba.tif") as src_ds: + expected_cs = src_ds.GetRasterBand(1).GetMaskBand().Checksum() + + with gdal.OpenEx( + "data/stefan_full_rgba.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE + ) as ds: + + def get_band(): + return ds.GetRasterBand(1).GetMaskBand() + + launch_threads(get_band, expected_cs) + + with gdal.OpenEx( + "data/stefan_full_rgba.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE + ) as ds: + band = ds.GetRasterBand(1).GetMaskBand() + + def get_band(): + return band + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_mask_of_mask_band(): + + with gdal.Open("data/stefan_full_rgba.tif") as src_ds: + expected_cs = src_ds.GetRasterBand(1).GetMaskBand().GetMaskBand().Checksum() + + with gdal.OpenEx( + "data/stefan_full_rgba.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE + ) as ds: + + def get_band(): + return ds.GetRasterBand(1).GetMaskBand().GetMaskBand() + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_mask_band_implicit_mem_ds(): + + with gdal.Open("data/stefan_full_rgba.tif") as src_ds: + ds = gdal.GetDriverByName("MEM").CreateCopy("", src_ds) + expected_cs = src_ds.GetRasterBand(1).GetMaskBand().Checksum() + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == expected_cs + + ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + + def get_band(): + return ds.GetRasterBand(1).GetMaskBand() + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_mask_band_explicit_mem_ds(): + + with gdal.Open("data/stefan_full_rgba.tif") as src_ds: + ds = gdal.GetDriverByName("MEM").Create( + "", src_ds.RasterXSize, src_ds.RasterYSize, 1 + ) + ds.GetRasterBand(1).CreateMaskBand(gdal.GMF_PER_DATASET) + ds.GetRasterBand(1).GetMaskBand().WriteRaster( + 0, + 0, + src_ds.RasterXSize, + src_ds.RasterYSize, + src_ds.GetRasterBand(1).GetMaskBand().ReadRaster(), + ) + + expected_cs = src_ds.GetRasterBand(1).GetMaskBand().Checksum() + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == expected_cs + + ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + + def get_band(): + return ds.GetRasterBand(1).GetMaskBand() + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_overview(tmp_path): + + tmpfilename = str(tmp_path / "byte.tif") + shutil.copy("data/byte.tif", tmpfilename) + with gdal.Open(tmpfilename, gdal.GA_Update) as ds: + ds.BuildOverviews("NEAR", [2]) + expected_cs = ds.GetRasterBand(1).GetOverview(0).Checksum() + + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + assert ds.GetRasterBand(1).GetOverviewCount() == 1 + assert ds.GetRasterBand(1).GetOverview(-1) is None + assert ds.GetRasterBand(1).GetOverview(1) is None + + def get_band(): + return ds.GetRasterBand(1).GetOverview(0) + + launch_threads(get_band, expected_cs) + + with gdal.OpenEx(tmpfilename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + band = ds.GetRasterBand(1).GetOverview(0) + + def get_band(): + return band + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_overview_mem_ds(): + + with gdal.Open("data/byte.tif") as src_ds: + ds = gdal.GetDriverByName("MEM").CreateCopy("", src_ds) + ds.BuildOverviews("NEAR", [2]) + expected_cs = ds.GetRasterBand(1).GetOverview(0).Checksum() + + ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + + assert ds.GetRasterBand(1).GetOverviewCount() == 1 + + def get_band(): + return ds.GetRasterBand(1).GetOverview(0) + + launch_threads(get_band, expected_cs) + + def get_band(): + return ds.GetRasterBand(1).GetSampleOverview(1) + + launch_threads(get_band, expected_cs) + + band = ds.GetRasterBand(1).GetOverview(0) + + def get_band(): + return band + + launch_threads(get_band, expected_cs) + + +def test_thread_safe_open_options(tmp_path): + + tmpfilename = str(tmp_path / "byte.tif") + shutil.copy("data/byte.tif", tmpfilename) + with gdal.Open(tmpfilename, gdal.GA_Update) as ds: + ds.BuildOverviews("NEAR", [2]) + expected_cs = ds.GetRasterBand(1).GetOverview(0).Checksum() + + with gdal.OpenEx( + tmpfilename, + gdal.OF_RASTER | gdal.OF_THREAD_SAFE, + open_options=["OVERVIEW_LEVEL=0"], + ) as ds: + + def get_band(): + return ds.GetRasterBand(1) + + launch_threads(get_band, expected_cs) + + +@pytest.mark.require_driver("HDF5") +@pytest.mark.require_driver("netCDF") +def test_thread_safe_reuse_same_driver_as_prototype(): + """Checks that thread-safe mode honours the opening driver""" + + with gdal.OpenEx( + "../gdrivers/data/netcdf/byte_hdf5_starting_at_offset_1024.nc", + gdal.OF_RASTER | gdal.OF_THREAD_SAFE, + allowed_drivers=["HDF5"], + ) as ds: + + ret = [False] + + def thread_func(): + assert ds.GetMetadataItem("_NCProperties") is not None + ret[0] = True + + t = threading.Thread(target=thread_func) + t.start() + t.join() + assert ret[0] + + +def test_thread_safe_no_rat(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + assert ds.GetRasterBand(1).GetDefaultRAT() is None + + +def test_thread_safe_rat(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + ds.GetRasterBand(1).SetDefaultRAT(gdal.RasterAttributeTable()) + ds = ds.GetThreadSafeDataset(gdal.OF_RASTER) + assert ds.GetRasterBand(1).GetDefaultRAT() is not None + + +@pytest.mark.require_driver("HFA") +def test_thread_safe_unsupported_rat(): + + with gdal.OpenEx( + "../gdrivers/data/hfa/87test.img", gdal.OF_RASTER | gdal.OF_THREAD_SAFE + ) as ds: + with pytest.raises( + Exception, + match="not supporting a non-GDALDefaultRasterAttributeTable implementation", + ): + ds.GetRasterBand(1).GetDefaultRAT() + + +def test_thread_safe_many_datasets(): + + tab_ds = [ + gdal.OpenEx( + "data/byte.tif" if (i % 3) < 2 else "data/utmsmall.tif", + gdal.OF_RASTER | gdal.OF_THREAD_SAFE, + ) + for i in range(100) + ] + + res = [True] + + def check(): + for _ in range(10): + for i, ds in enumerate(tab_ds): + if ds.GetRasterBand(1).Checksum() != (4672 if (i % 3) < 2 else 50054): + res[0] = False + + threads = [threading.Thread(target=check) for i in range(2)] + for t in threads: + t.start() + for t in threads: + t.join() + assert res[0] + + +def test_thread_safe_BeginAsyncReader(): + + with gdal.OpenEx("data/byte.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + with pytest.raises(Exception, match="not supported"): + ds.BeginAsyncReader(0, 0, ds.RasterXSize, ds.RasterYSize) + + +def test_thread_safe_GetVirtualMem(): + + pytest.importorskip("numpy") + pytest.importorskip("osgeo.gdal_array") + + with gdal.OpenEx("data/byte.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + with pytest.raises(Exception, match="not supported"): + ds.GetRasterBand(1).GetVirtualMemAutoArray(gdal.GF_Read) + + +def test_thread_safe_GetMetadadata(tmp_vsimem): + + filename = str(tmp_vsimem / "test.tif") + with gdal.GetDriverByName("GTiff").Create(filename, 1, 1) as ds: + ds.SetMetadataItem("foo", "bar") + ds.GetRasterBand(1).SetMetadataItem("bar", "baz") + + with gdal.OpenEx(filename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + assert ds.GetMetadataItem("foo") == "bar" + assert ds.GetMetadataItem("not existing") is None + assert ds.GetMetadata() == {"foo": "bar"} + assert ds.GetMetadata("not existing") == {} + assert ds.GetRasterBand(1).GetMetadataItem("bar") == "baz" + assert ds.GetRasterBand(1).GetMetadataItem("not existing") is None + assert ds.GetRasterBand(1).GetMetadata() == {"bar": "baz"} + assert ds.GetRasterBand(1).GetMetadata("not existing") == {} + + +def test_thread_safe_GetUnitType(tmp_vsimem): + + filename = str(tmp_vsimem / "test.tif") + with gdal.GetDriverByName("GTiff").Create(filename, 1, 1) as ds: + ds.GetRasterBand(1).SetUnitType("foo") + + with gdal.OpenEx(filename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + assert ds.GetRasterBand(1).GetUnitType() == "foo" + + +def test_thread_safe_GetColorTable(tmp_vsimem): + + filename = str(tmp_vsimem / "test.tif") + with gdal.GetDriverByName("GTiff").Create(filename, 1, 1) as ds: + ct = gdal.ColorTable() + ct.SetColorEntry(0, (1, 2, 3, 255)) + ds.GetRasterBand(1).SetColorTable(ct) + + with gdal.OpenEx(filename, gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + res = [None] + + def thread_job(): + res[0] = ds.GetRasterBand(1).GetColorTable() + + t = threading.Thread(target=thread_job) + t.start() + t.join() + assert res[0] + assert res[0].GetColorEntry(0) == (1, 2, 3, 255) + ct = ds.GetRasterBand(1).GetColorTable() + assert ct.GetColorEntry(0) == (1, 2, 3, 255) + + +def test_thread_safe_GetSpatialRef(): + + with gdal.OpenEx("data/byte.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE) as ds: + + res = [True] + + def check(): + for i in range(100): + + if len(ds.GetGCPs()) != 0: + res[0] = False + assert False + + if ds.GetGCPSpatialRef(): + res[0] = False + assert False + + if ds.GetGCPProjection(): + res[0] = False + assert False + + srs = ds.GetSpatialRef() + if not srs: + res[0] = False + assert False + if not srs.IsProjected(): + res[0] = False + assert False + if "NAD27 / UTM zone 11N" not in srs.ExportToWkt(): + res[0] = False + assert False + + if "NAD27 / UTM zone 11N" not in ds.GetProjectionRef(): + res[0] = False + assert False + + threads = [threading.Thread(target=check) for i in range(2)] + for t in threads: + t.start() + for t in threads: + t.join() + assert res[0] + + +def test_thread_safe_GetGCPs(): + + with gdal.OpenEx( + "data/byte_gcp_pixelispoint.tif", gdal.OF_RASTER | gdal.OF_THREAD_SAFE + ) as ds: + + res = [True] + + def check(): + for i in range(100): + + if len(ds.GetGCPs()) != 4: + res[0] = False + assert False + + gcp_srs = ds.GetGCPSpatialRef() + if gcp_srs is None: + res[0] = False + assert False + if not gcp_srs.IsGeographic(): + res[0] = False + assert False + if "unretrievable - using WGS84" not in gcp_srs.ExportToWkt(): + res[0] = False + assert False + + gcp_wkt = ds.GetGCPProjection() + if not gcp_wkt: + res[0] = False + assert False + if "unretrievable - using WGS84" not in gcp_wkt: + res[0] = False + assert False + + if ds.GetSpatialRef(): + res[0] = False + assert False + if ds.GetProjectionRef() != "": + res[0] = False + assert False + + threads = [threading.Thread(target=check) for i in range(2)] + for t in threads: + t.start() + for t in threads: + t.join() + assert res[0] diff --git a/autotest/gcore/tiff_ovr.py b/autotest/gcore/tiff_ovr.py index ba49b4b3fb45..990b3d84aa5d 100755 --- a/autotest/gcore/tiff_ovr.py +++ b/autotest/gcore/tiff_ovr.py @@ -11,23 +11,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -122,6 +106,10 @@ def mfloat32_tif(tmp_path): yield dst_fname +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_ovr_1(mfloat32_tif, both_endian): ds = gdal.Open(mfloat32_tif) @@ -151,6 +139,10 @@ def test_tiff_ovr_1(mfloat32_tif, both_endian): # Open target file in update mode, and create internal overviews. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_ovr_3(mfloat32_tif, both_endian): src_ds = gdal.Open(mfloat32_tif, gdal.GA_Update) @@ -279,6 +271,8 @@ def cbk(pct, _, user_data): callback_data=tab, options=["USE_RRD=YES"], ) + if gdal.GetLastErrorMsg() == "This build does not support creating .aux overviews": + pytest.skip(gdal.GetLastErrorMsg()) assert tab[0] == 1.0 try: @@ -531,6 +525,10 @@ def test_tiff_ovr_12(tmp_path, both_endian): # Test gaussian resampling +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_ovr_13(mfloat32_tif, both_endian): ds = gdal.Open(mfloat32_tif) @@ -608,6 +606,10 @@ def test_tiff_ovr_15(tmp_path, both_endian): # Test mode resampling on non-byte dataset +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_ovr_16(tmp_path, both_endian): tif_fname = str(tmp_path / "ovr16.tif") @@ -2642,7 +2644,9 @@ def test_tiff_ovr_fallback_to_multiband_overview_generate(): "data/byte.tif", options="-b 1 -b 1 -b 1 -co INTERLEAVE=BAND -co TILED=YES -outsize 1024 1024", ) - with gdaltest.config_option("GDAL_OVR_CHUNK_MAX_SIZE", "1000"): + with gdaltest.config_options( + {"GDAL_OVR_CHUNK_MAX_SIZE": "1000", "GDAL_OVR_TEMP_DRIVER": "MEM"} + ): ds.BuildOverviews("NEAR", overviewlist=[2, 4, 8]) ds = None diff --git a/autotest/gcore/tiff_read.py b/autotest/gcore/tiff_read.py index 152687229ba3..150276bd0b79 100755 --- a/autotest/gcore/tiff_read.py +++ b/autotest/gcore/tiff_read.py @@ -40,6 +40,8 @@ from osgeo import gdal, osr +pytestmark = pytest.mark.require_driver("HFA") + init_list = [ ("byte.tif", 1, 4672), ("uint16_sgilog.tif", 1, 4672), @@ -774,6 +776,7 @@ def test_tiff_read_stats_from_pam(tmp_path): # Test extracting georeferencing from a .TAB file +@pytest.mark.require_driver("MapInfo File") def test_tiff_read_from_tab(tmp_path): ds = gdal.GetDriverByName("GTiff").Create(tmp_path / "tiff_read_from_tab.tif", 1, 1) @@ -2822,6 +2825,7 @@ def test_tiff_read_one_strip_no_bytecount(): # Test GDAL_GEOREF_SOURCES +@pytest.mark.require_driver("MapInfo File") @pytest.mark.parametrize( "config_option_value,copy_pam,copy_worldfile,copy_tabfile,expected_srs,expected_gt", [ @@ -3027,6 +3031,7 @@ def test_tiff_read_nogeoref( # Test GDAL_GEOREF_SOURCES +@pytest.mark.require_driver("MapInfo File") @pytest.mark.parametrize( "config_option_value,copy_pam,copy_worldfile,copy_tabfile,expected_srs,expected_gt", [ @@ -3261,7 +3266,7 @@ def test_tiff_read_gcp_internal_and_auxxml( # Test reading .tif + .aux -class myHandlerClass(object): +class myHandlerClass: def __init__(self): self.msg = None @@ -5189,6 +5194,10 @@ def test_tiff_read_webp_lossless_rgba_alpha_fully_opaque(): # Test complex scenario of https://github.com/OSGeo/gdal/issues/9563 +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_creation_option("GTiff", "JPEG") def test_tiff_read_jpeg_cached_multi_range_issue_9563(tmp_vsimem): @@ -5315,3 +5324,37 @@ def error_handler(type, code, msg): webserver.server_stop(webserver_process, webserver_port) gdal.VSICurlClearCache() + + +############################################################################### +# Test reading a unrecognized value in the special COLORINTERP item in +# GDAL_METADATA + + +def test_tiff_read_unrecognized_color_interpretation(): + + ds = gdal.Open("data/gtiff/unknown_colorinterp.tif") + assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_Undefined + assert ds.GetRasterBand(1).GetMetadataItem("COLOR_INTERPRETATION") == "XXXX" + + +############################################################################### +# Check that cleaning overviews on a DIMAP2 GeoTIFF file with external overviews +# does not cause the DIMAP XML file to be cleaned + + +def test_tiff_read_ovr_dimap_pleiades(tmp_path): + + shutil.copytree("../gdrivers/data/dimap2/bundle", tmp_path / "bundle") + filename = str(tmp_path / "bundle" / "IMG_foo_R1C1.TIF") + ds = gdal.Open(filename) + ds.BuildOverviews("NEAR", [2]) + ds = None + ds = gdal.Open(filename + ".ovr") + assert ds.GetFileList() == [filename + ".ovr"] + ds = None + ds = gdal.Open(filename) + ds.BuildOverviews("", []) + ds = None + # Check that cleaning overviews did not suppress the DIMAP XML file + assert os.path.exists(tmp_path / "bundle" / "DIM_foo.XML") diff --git a/autotest/gcore/tiff_read_subifds.py b/autotest/gcore/tiff_read_subifds.py index 922d83c36e3e..8aec882e5177 100755 --- a/autotest/gcore/tiff_read_subifds.py +++ b/autotest/gcore/tiff_read_subifds.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2019, Thomas Bonfort # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gcore/tiff_srs.py b/autotest/gcore/tiff_srs.py index a4d9d6c9c9a1..f4069357001d 100755 --- a/autotest/gcore/tiff_srs.py +++ b/autotest/gcore/tiff_srs.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gcore/tiff_write.py b/autotest/gcore/tiff_write.py index 03aae9ca57e0..3e2c8d9de67b 100755 --- a/autotest/gcore/tiff_write.py +++ b/autotest/gcore/tiff_write.py @@ -212,6 +212,10 @@ def test_tiff_write_4(): # Write a file with GCPs. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_5(): src_ds = gdal.Open("data/gcps.vrt") @@ -434,6 +438,10 @@ def test_tiff_write_14(): # file using the PROFILE creation option with CreateCopy() +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_15(): ds_in = gdal.Open("data/byte.vrt") @@ -484,6 +492,10 @@ def test_tiff_write_15(): # file using the PROFILE creation option with Create() +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_16(): ds_in = gdal.Open("data/byte.vrt") @@ -548,6 +560,10 @@ def test_tiff_write_16(): # Test writing a TIFF with an RPC tag. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_17(): # Translate RPC controlled data to GeoTIFF. @@ -608,6 +624,10 @@ def test_tiff_write_17(): # case (#3996) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_17_disable_readdir(): with gdal.config_option("GDAL_DISABLE_READDIR_ON_OPEN", "TRUE"): test_tiff_write_17() @@ -617,6 +637,10 @@ def test_tiff_write_17_disable_readdir(): # Test writing a TIFF with an RPB file and IMD file. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_18(): # Translate RPC controlled data to GeoTIFF. @@ -713,6 +737,10 @@ def test_tiff_write_imd_with_space_in_values(): # case (#3996) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_18_disable_readdir(): with gdal.config_option("GDAL_DISABLE_READDIR_ON_OPEN", "TRUE"): test_tiff_write_18() @@ -722,6 +750,10 @@ def test_tiff_write_18_disable_readdir(): # Test writing a TIFF with an _RPC.TXT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_rpc_txt(): # Translate RPC controlled data to GeoTIFF. @@ -774,6 +806,10 @@ def test_tiff_write_rpc_txt(): # Test writing a TIFF with an RPC in .aux.xml +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_rpc_in_pam(): ds_in = gdal.Open("data/rpc.vrt") @@ -1269,6 +1305,10 @@ def test_tiff_write_31(): # Create a rotated image +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_32(): ds_in = gdal.Open("data/byte.vrt") @@ -1309,6 +1349,10 @@ def test_tiff_write_32(): # (BASELINE is tested by tiff_write_15) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_33(): ds_in = gdal.Open("data/byte.vrt") @@ -1464,6 +1508,10 @@ def tiff_write_big_odd_bits(vrtfilename, tmpfilename, nbits, interleaving): # Test copy with NBITS=9, INTERLEAVE=PIXEL +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_36(): return tiff_write_big_odd_bits("data/uint16_3band.vrt", "tmp/tw_36.tif", 9, "PIXEL") @@ -1472,6 +1520,10 @@ def test_tiff_write_36(): # Test copy with NBITS=9, INTERLEAVE=BAND +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_37(): return tiff_write_big_odd_bits("data/uint16_3band.vrt", "tmp/tw_37.tif", 9, "BAND") @@ -1480,6 +1532,10 @@ def test_tiff_write_37(): # Test copy with NBITS=12, INTERLEAVE=PIXEL +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_38(): return tiff_write_big_odd_bits( "data/uint16_3band.vrt", "tmp/tw_38.tif", 12, "PIXEL" @@ -1490,6 +1546,10 @@ def test_tiff_write_38(): # Test copy with NBITS=12, INTERLEAVE=BAND +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_39(): return tiff_write_big_odd_bits("data/uint16_3band.vrt", "tmp/tw_39.tif", 12, "BAND") @@ -1498,6 +1558,10 @@ def test_tiff_write_39(): # Test copy with NBITS=17, INTERLEAVE=PIXEL +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_40(): return tiff_write_big_odd_bits("data/uint32_3band.vrt", "tmp/tw_40tif", 17, "PIXEL") @@ -1506,6 +1570,10 @@ def test_tiff_write_40(): # Test copy with NBITS=17, INTERLEAVE=BAND +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_41(): return tiff_write_big_odd_bits("data/uint32_3band.vrt", "tmp/tw_41.tif", 17, "BAND") @@ -1514,6 +1582,10 @@ def test_tiff_write_41(): # Test copy with NBITS=24, INTERLEAVE=PIXEL +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_42(): return tiff_write_big_odd_bits( "data/uint32_3band.vrt", "tmp/tw_42.tif", 24, "PIXEL" @@ -1524,6 +1596,10 @@ def test_tiff_write_42(): # Test copy with NBITS=24, INTERLEAVE=BAND +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_43(): return tiff_write_big_odd_bits("data/uint32_3band.vrt", "tmp/tw_43.tif", 24, "BAND") @@ -4892,6 +4968,10 @@ def test_tiff_write_120(): # Test error cases of COPY_SRC_OVERVIEWS creation option +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_121(): # Test when the overview band is NULL @@ -5326,6 +5406,10 @@ def test_tiff_write_125(): # Test implicit JPEG-in-TIFF overviews +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_creation_option("GTiff", "JPEG") @pytest.mark.require_driver("JPEG") def test_tiff_write_126(): @@ -6444,6 +6528,10 @@ def test_tiff_write_134(): # Test clearing GCPs (#5945) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_135(): # Simple clear @@ -7876,6 +7964,10 @@ def test_tiff_write_160(): # Test setting GCPs on an image with already a geotransform and vice-versa (#6751) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_161(): ds = gdaltest.tiff_drv.Create("/vsimem/tiff_write_161.tif", 1, 1) @@ -7910,6 +8002,10 @@ def test_tiff_write_161(): # Test creating a JPEG compressed file with big tiles (#6757) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_creation_option("GTiff", "JPEG") def test_tiff_write_162(): @@ -9252,6 +9348,10 @@ def test_tiff_write_compression_create_and_createcopy(): # Attempt at creating a file with more tile arrays larger than 2 GB +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_tiff_write_too_many_tiles(): src_ds = gdal.Open( @@ -9649,6 +9749,74 @@ def test_tiff_write_jpegxl_alpha_distance_zero(): gdal.Unlink(filename) +############################################################################### + + +@pytest.mark.require_creation_option("GTiff", "JXL_ALPHA_DISTANCE") +def test_tiff_write_jpegxl_five_bands_lossy(tmp_vsimem): + + outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_five_bands_lossy.tif") + gdal.Translate( + outfilename, + "data/byte.tif", + options="-co COMPRESS=JXL -co JXL_LOSSLESS=NO -co JXL_DISTANCE=3 -b 1 -b 1 -b 1 -b 1 -b 1", + ) + ds = gdal.Open(outfilename) + assert ds.GetRasterBand(3).Checksum() not in (0, 4672) + assert ds.GetRasterBand(4).Checksum() not in (0, 4672) + assert ds.GetRasterBand(5).Checksum() not in (0, 4672) + + +############################################################################### + + +@pytest.mark.require_creation_option("GTiff", "JXL_ALPHA_DISTANCE") +def test_tiff_write_jpegxl_five_bands_lossless(tmp_vsimem): + + outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_five_bands_lossy.tif") + gdal.Translate( + outfilename, + "data/byte.tif", + options="-co COMPRESS=JXL -co JXL_LOSSLESS=YES -b 1 -b 1 -b 1 -b 1 -b 1", + ) + ds = gdal.Open(outfilename) + for i in range(5): + assert ds.GetRasterBand(i + 1).Checksum() == 4672 + + +############################################################################### + + +@pytest.mark.require_creation_option("GTiff", "JXL") +def test_tiff_write_jpegxl_float16(tmp_vsimem): + + outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_float16") + src_ds = gdal.Open("data/float16.tif") + gdal.GetDriverByName("GTiff").CreateCopy( + outfilename, src_ds, options=["COMPRESS=JXL", "JXL_LOSSLESS=YES"] + ) + ds = gdal.Open(outfilename) + assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32 + assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "16" + assert ds.GetRasterBand(1).Checksum() == 4672 + + +############################################################################### + + +@pytest.mark.require_creation_option("GTiff", "JXL") +@pytest.mark.parametrize("dt,nbits", [(gdal.GDT_Float64, None), (gdal.GDT_Byte, 1)]) +@gdaltest.enable_exceptions() +def test_tiff_write_jpegxl_errors(tmp_vsimem, dt, nbits): + + outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_errors") + with pytest.raises(Exception): + options = {"COMPRESS": "JXL"} + if nbits: + options["NBITS"] = str(nbits) + gdal.GetDriverByName("GTiff").Create(outfilename, 1, 1, 1, dt, options=options) + + ############################################################################### # Test creating overviews with NaN nodata @@ -11597,3 +11765,166 @@ def test_tiff_write_colormap_256_mult_factor(tmp_vsimem): and ct.GetColorEntry(1) == (0, 1, 2, 255) and ct.GetColorEntry(2) == (254, 254, 254, 255) ), "Wrong color table entry." + + +############################################################################### +@pytest.mark.require_creation_option("GTiff", "JPEG") +@pytest.mark.parametrize( + "xsize,ysize,options,expected_error_msg", + [ + ( + 65501, + 1, + ["COMPRESS=JPEG"], + "COMPRESS=JPEG is only compatible of un-tiled images whose width is lesser or equal to 65500 pixels", + ), + ( + 1, + 65501, + ["COMPRESS=JPEG", "BLOCKYSIZE=65501"], + "COMPRESS=JPEG is only compatible of images whose BLOCKYSIZE is lesser or equal to 65500 pixels", + ), + ( + 1, + 1, + ["COMPRESS=JPEG", "TILED=YES", "BLOCKXSIZE=65536"], + "COMPRESS=JPEG is only compatible of tiled images whose BLOCKXSIZE is lesser or equal to 65500 pixels", + ), + ( + 1, + 1, + ["COMPRESS=JPEG", "TILED=YES", "BLOCKYSIZE=65536"], + "COMPRESS=JPEG is only compatible of images whose BLOCKYSIZE is lesser or equal to 65500 pixels", + ), + ], +) +@gdaltest.enable_exceptions() +def test_tiff_write_too_large_jpeg( + tmp_vsimem, xsize, ysize, options, expected_error_msg +): + + filename = str(tmp_vsimem / "test.tif") + with pytest.raises(Exception, match=expected_error_msg): + gdal.GetDriverByName("GTiff").Create(filename, xsize, ysize, options=options) + + +############################################################################### +@pytest.mark.require_creation_option("GTiff", "WEBP") +@pytest.mark.parametrize( + "xsize,ysize,options,expected_error_msg", + [ + ( + 16384, + 1, + ["COMPRESS=WEBP"], + "COMPRESS=WEBP is only compatible of un-tiled images whose width is lesser or equal to 16383 pixels", + ), + ( + 1, + 16384, + ["COMPRESS=WEBP", "BLOCKYSIZE=16384"], + "COMPRESS=WEBP is only compatible of images whose BLOCKYSIZE is lesser or equal to 16383 pixels", + ), + ( + 1, + 1, + ["COMPRESS=WEBP", "TILED=YES", "BLOCKXSIZE=16384"], + "COMPRESS=WEBP is only compatible of tiled images whose BLOCKXSIZE is lesser or equal to 16383 pixels", + ), + ( + 1, + 1, + ["COMPRESS=WEBP", "TILED=YES", "BLOCKYSIZE=16384"], + "COMPRESS=WEBP is only compatible of images whose BLOCKYSIZE is lesser or equal to 16383 pixels", + ), + ], +) +@gdaltest.enable_exceptions() +def test_tiff_write_too_large_webp( + tmp_vsimem, xsize, ysize, options, expected_error_msg +): + + filename = str(tmp_vsimem / "test.tif") + with pytest.raises(Exception, match=expected_error_msg): + gdal.GetDriverByName("GTiff").Create(filename, xsize, ysize, options=options) + + +############################################################################### +# Test writing/reading band IMAGERY metadata + + +def test_tiff_write_band_IMAGERY(tmp_vsimem): + + filename = str(tmp_vsimem / "test.tif") + with gdal.GetDriverByName("GTiff").Create(filename, 1, 1) as ds: + ds.GetRasterBand(1).SetMetadataItem("foo", "bar", "IMAGERY") + with gdal.Open(filename) as ds: + assert ds.GetRasterBand(1).GetMetadataDomainList() == ["IMAGERY"] + with gdal.Open(filename) as ds: + assert ds.GetRasterBand(1).GetMetadataItem("foo", "IMAGERY") == "bar" + with gdal.Open(filename) as ds: + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {"foo": "bar"} + + filename2 = str(tmp_vsimem / "test2.tif") + + with gdal.Open(filename) as ds: + gdal.GetDriverByName("GTiff").CreateCopy(filename2, ds) + with gdal.Open(filename2) as ds: + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {"foo": "bar"} + + with gdal.Open(filename) as ds: + gdal.GetDriverByName("GTiff").CreateCopy( + filename2, ds, options=["COPY_SRC_MDD=YES"] + ) + with gdal.Open(filename2) as ds: + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {"foo": "bar"} + + with gdal.Open(filename) as ds: + gdal.GetDriverByName("GTiff").CreateCopy( + filename2, ds, options=["COPY_SRC_MDD=NO"] + ) + with gdal.Open(filename2) as ds: + assert ds.GetRasterBand(1).GetMetadataDomainList() is None + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {} + + with gdal.Open(filename) as ds: + gdal.GetDriverByName("GTiff").CreateCopy( + filename2, ds, options=["SRC_MDD=not_existing"] + ) + with gdal.Open(filename2) as ds: + assert ds.GetRasterBand(1).GetMetadataDomainList() is None + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {} + + with gdal.Open(filename) as ds: + gdal.GetDriverByName("GTiff").CreateCopy( + filename2, ds, options=["SRC_MDD=not_existing", "SRC_MDD=IMAGERY"] + ) + with gdal.Open(filename2) as ds: + assert ds.GetRasterBand(1).GetMetadata_Dict("IMAGERY") == {"foo": "bar"} + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. + + +@pytest.mark.parametrize( + "src_filename,creation_options", + [ + ("data/gtiff/byte_little_endian_golden.tif", []), + ("data/gtiff/uint16_little_endian_golden.tif", []), + ("data/gtiff/float32_little_endian_golden.tif", []), + ( + "data/gtiff/byte_little_endian_tiled_lzw_golden.tif", + ["TILED=YES", "BLOCKXSIZE=16", "BLOCKYSIZE=16", "COMPRESS=LZW"], + ), + ], +) +def test_tiff_write_check_golden_file(tmp_path, src_filename, creation_options): + + out_filename = str(tmp_path / "test.tif") + with gdal.Open(src_filename) as src_ds: + gdal.GetDriverByName("GTiff").CreateCopy( + out_filename, src_ds, options=["ENDIANNESS=LITTLE"] + creation_options + ) + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size + assert open(src_filename, "rb").read() == open(out_filename, "rb").read() diff --git a/autotest/gcore/transformer.py b/autotest/gcore/transformer.py index 2be372a75de9..28d4b9acaac2 100644 --- a/autotest/gcore/transformer.py +++ b/autotest/gcore/transformer.py @@ -11,23 +11,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -70,6 +54,10 @@ def test_transformer_1(): # Test GCP based transformer with polynomials. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_2(): ds = gdal.Open("data/gcps.vrt") @@ -98,6 +86,10 @@ def test_transformer_2(): # Test GCP based transformer with thin plate splines. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_3(): ds = gdal.Open("data/gcps.vrt") @@ -126,6 +118,10 @@ def test_transformer_3(): # Test geolocation based transformer. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_4(): ds = gdal.Open("data/sstgeo.vrt") @@ -154,6 +150,10 @@ def test_transformer_4(): # Test RPC based transformer. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_5(): ds = gdal.Open("data/rpc.vrt") @@ -364,6 +364,10 @@ def test_transformer_5(): # Test RPC convergence bug (bug # 5395) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_6(): ds = gdal.Open("data/rpc_5395.vrt") @@ -402,6 +406,10 @@ def test_transformer_7(): # Test handling of nodata in RPC DEM (#5680) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_8(): ds = gdal.Open("data/rpc.vrt") @@ -448,6 +456,10 @@ def test_transformer_8(): # Test RPC DEM line optimization +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_9(): ds = gdal.Open("data/rpc.vrt") @@ -504,6 +516,10 @@ def test_transformer_9(): # Test RPC DEM transform from geoid height to ellipsoidal height +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("GTX") def test_transformer_10(): @@ -637,6 +653,10 @@ def test_transformer_11(): # Test degenerate cases of TPS transformer +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_12(): ds = gdal.Open( @@ -834,6 +854,10 @@ def test_transformer_14(): # beyond +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_15(): ds = gdal.GetDriverByName("MEM").Create("", 6600, 4400) @@ -933,6 +957,10 @@ def test_transformer_15(): # (we mostly test that the parameters are well recognized and serialized) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_16(): gdal.Translate( @@ -966,6 +994,10 @@ def test_transformer_16(): # Test RPC DEM with unexisting RPC DEM file +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_17(): ds = gdal.Open("data/rpc.vrt") @@ -1018,6 +1050,10 @@ def test_transformer_no_reverse_method(): # Test precision of GCP based transformer with thin plate splines and lots of GCPs (2115). +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_tps_precision(): ds = gdal.Open("data/gcps_2115.vrt") @@ -1099,6 +1135,10 @@ def test_transformer_image_no_srs(): # Test RPC_DEM_SRS by adding vertical component egm 96 geoid +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_dem_overrride_srs(): ds = gdal.Open("data/rpc.vrt") ds_dem = gdal.GetDriverByName("GTiff").Create("/vsimem/dem.tif", 100, 100, 1) @@ -1191,6 +1231,10 @@ def test_transformer_SuggestedWarpOutput_from_options(): # Test GCP antimerdian unwrap (https://github.com/OSGeo/gdal/issues/8371) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_transformer_gcp_antimeridian_unwrap(): ds = gdal.Open("data/test_gcp_antimeridian_unwrap.vrt") diff --git a/autotest/gcore/virtualmem.py b/autotest/gcore/virtualmem.py index ccedac52682d..3de02dd1e3aa 100755 --- a/autotest/gcore/virtualmem.py +++ b/autotest/gcore/virtualmem.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/gcore/vrt_read.py b/autotest/gcore/vrt_read.py index 2c4d319f4e33..3503a55c21d8 100755 --- a/autotest/gcore/vrt_read.py +++ b/autotest/gcore/vrt_read.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -42,6 +26,10 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) ############################################################################### @pytest.fixture(autouse=True, scope="module") @@ -2493,30 +2481,68 @@ def test_vrt_read_top_and_bottom_strips_average(): @pytest.mark.parametrize( - "input_datatype", [gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_Int16] -) -@pytest.mark.parametrize("vrt_type", ["Byte", "UInt16", "Int16"]) -@pytest.mark.parametrize("nodata", [0, 254]) -@pytest.mark.parametrize( - "request_type", [gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_Int16] + "input_datatype,vrt_type,nodata,vrt_nodata,request_type", + [ + (gdal.GDT_Byte, "Byte", 0, 255, gdal.GDT_Byte), + (gdal.GDT_Byte, "Byte", 254, 255, gdal.GDT_Byte), + (gdal.GDT_Byte, "Int8", 254, 255, gdal.GDT_Byte), + (gdal.GDT_Byte, "Byte", 254, 127, gdal.GDT_Int8), + (gdal.GDT_Byte, "UInt16", 254, 255, gdal.GDT_Byte), + (gdal.GDT_Byte, "Byte", 254, 255, gdal.GDT_UInt16), + (gdal.GDT_Int8, "Int8", 0, 127, gdal.GDT_Int8), + (gdal.GDT_Int8, "Int16", 0, 127, gdal.GDT_Int8), + (gdal.GDT_UInt16, "UInt16", 0, 65535, gdal.GDT_UInt16), + (gdal.GDT_Int16, "Int16", 0, 32767, gdal.GDT_Int16), + (gdal.GDT_UInt32, "UInt32", 0, (1 << 31) - 1, gdal.GDT_UInt32), + (gdal.GDT_Int32, "Int32", 0, (1 << 30) - 1, gdal.GDT_Int32), + (gdal.GDT_Int32, "Float32", 0, (1 << 30) - 1, gdal.GDT_Float64), + (gdal.GDT_UInt64, "UInt64", 0, (1 << 63) - 1, gdal.GDT_UInt64), + (gdal.GDT_Int64, "Int64", 0, (1 << 62) - 1, gdal.GDT_Int64), + (gdal.GDT_Int64, "Float32", 0, (1 << 62), gdal.GDT_Int64), + (gdal.GDT_Float32, "Float32", 0, 1.5, gdal.GDT_Float32), + (gdal.GDT_Float32, "Float32", 0, 1.5, gdal.GDT_Float64), + (gdal.GDT_Float32, "Float64", 0, 1.5, gdal.GDT_Float32), + (gdal.GDT_Float32, "Float64", 0, 1.5, gdal.GDT_Float64), + (gdal.GDT_Float64, "Float64", 0, 1.5, gdal.GDT_Float64), + (gdal.GDT_Float64, "Float32", 0, 1.5, gdal.GDT_Float64), + ], ) def test_vrt_read_complex_source_nodata( - tmp_vsimem, input_datatype, vrt_type, nodata, request_type + tmp_vsimem, input_datatype, vrt_type, nodata, vrt_nodata, request_type ): - - if input_datatype == gdal.GDT_Byte: - array_type = "B" - elif input_datatype == gdal.GDT_UInt16: - array_type = "H" - elif input_datatype == gdal.GDT_Int16: - array_type = "h" + def get_array_type(dt): + m = { + gdal.GDT_Byte: "B", + gdal.GDT_Int8: "b", + gdal.GDT_UInt16: "H", + gdal.GDT_Int16: "h", + gdal.GDT_UInt32: "I", + gdal.GDT_Int32: "i", + gdal.GDT_UInt64: "Q", + gdal.GDT_Int64: "q", + gdal.GDT_Float32: "f", + gdal.GDT_Float64: "d", + } + return m[dt] + + if input_datatype in (gdal.GDT_Float32, gdal.GDT_Float64): + input_val = 1.75 + if vrt_type in ("Float32", "Float64") and request_type in ( + gdal.GDT_Float32, + gdal.GDT_Float64, + ): + expected_val = input_val + else: + expected_val = math.round(input_val) else: - assert False + input_val = 1 + expected_val = input_val + input_data = array.array( - array_type, + get_array_type(input_datatype), [ nodata, - 1, + input_val, 2, 3, nodata, # EOL @@ -2553,7 +2579,7 @@ def test_vrt_read_complex_source_nodata( ds.Close() complex_xml = f""" - 255 + {vrt_nodata} {input_filename} 1 @@ -2563,24 +2589,16 @@ def test_vrt_read_complex_source_nodata( """ vrt_ds = gdal.Open(complex_xml) - if request_type == gdal.GDT_Byte: - array_request_type = "B" - elif request_type == gdal.GDT_UInt16: - array_request_type = "H" - elif request_type == gdal.GDT_Int16: - array_request_type = "h" - else: - assert False got_data = vrt_ds.ReadRaster(buf_type=request_type) - got_data = struct.unpack(array_request_type * (5 * 6), got_data) + got_data = struct.unpack(get_array_type(request_type) * (5 * 6), got_data) assert got_data == ( - 255, - 1, + vrt_nodata, + expected_val, 2, 3, - 255, # EOL + vrt_nodata, # EOL 4, - 255, + vrt_nodata, 5, 6, 7, # EOL @@ -2591,18 +2609,18 @@ def test_vrt_read_complex_source_nodata( 20, # EOL 8, 9, - 255, + vrt_nodata, 10, 11, # EOL - 255, - 255, - 255, - 255, - 255, # EOL + vrt_nodata, + vrt_nodata, + vrt_nodata, + vrt_nodata, + vrt_nodata, # EOL 12, 13, 14, - 255, + vrt_nodata, 15, # EOL ) @@ -2784,3 +2802,64 @@ def test_vrt_read_multi_threaded_disabled_since_overlapping_sources(): assert ( vrt_ds.GetMetadataItem("MULTI_THREADED_RASTERIO_LAST_USED", "__DEBUG__") == "0" ) + + +############################################################################### +# Test reading a VRT with a inside a + + +def test_vrt_read_nested_VRTDataset(): + + ds = gdal.Open("data/vrt/nested_VRTDataset.vrt") + assert ds.GetRasterBand(1).Checksum() == 4672 + + +############################################################################### +# Test updating a VRT with a inside a + + +def test_vrt_update_nested_VRTDataset(tmp_vsimem): + + gdal.FileFromMemBuffer(tmp_vsimem / "byte.tif", open("data/byte.tif", "rb").read()) + gdal.Mkdir(tmp_vsimem / "vrt", 0o755) + vrt_filename = tmp_vsimem / "vrt" / "nested_VRTDataset.vrt" + gdal.FileFromMemBuffer( + vrt_filename, open("data/vrt/nested_VRTDataset.vrt", "rb").read() + ) + + with gdal.Open(vrt_filename) as ds: + assert ds.GetRasterBand(1).Checksum() == 4672 + assert ds.GetRasterBand(1).GetMinimum() is None + vrt_stats = ds.GetRasterBand(1).ComputeStatistics(False) + assert vrt_stats[0] == 74 + + # Check that statistics have been serialized in the VRT + with gdal.Open(vrt_filename) as ds: + assert ds.GetRasterBand(1).Checksum() == 4672 + assert ds.GetRasterBand(1).GetMinimum() == 74 + + +############################################################################### +# Test reading a VRT with a ComplexSource of type CFloat32 + + +def test_vrt_read_cfloat32_complex_source_as_float32(): + + ds = gdal.Open("data/vrt/complex_non_zero_real_zero_imag.vrt") + assert struct.unpack("f" * 8, ds.ReadRaster()) == (1, 0, 1, 0, 1, 0, 1, 0) + assert struct.unpack("f" * 4, ds.ReadRaster(buf_type=gdal.GDT_Float32)) == ( + 1, + 1, + 1, + 1, + ) + + +############################################################################### +# Test reading a VRT with a ComplexSource of type Float32 (from a underlying CFloat32 source) + + +def test_vrt_read_float32_complex_source_from_cfloat32(): + + ds = gdal.Open("data/vrt/complex_non_zero_real_zero_imag_as_float32.vrt") + assert struct.unpack("f" * 4, ds.ReadRaster()) == (1, 1, 1, 1) diff --git a/autotest/gcore/vrtmisc.py b/autotest/gcore/vrtmisc.py index 472f0c9bdc56..52bd757867d0 100755 --- a/autotest/gcore/vrtmisc.py +++ b/autotest/gcore/vrtmisc.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -36,10 +20,16 @@ import tempfile from pathlib import Path +import gdaltest import pytest from osgeo import gdal, osr +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Test linear scaling @@ -688,6 +678,26 @@ def test_vrtmisc_blocksize_gdal_translate_direct(): # Test setting block size through creation options +def test_vrtmisc_blocksize_gdalbuildvrt(): + filename = "/vsimem/test_vrtmisc_blocksize_gdalbuildvrt.vrt" + vrt_ds = gdal.BuildVRT( + filename, ["data/byte.tif"], creationOptions=["BLOCKXSIZE=32", "BLOCKYSIZE=48"] + ) + vrt_ds = None + + vrt_ds = gdal.Open(filename) + blockxsize, blockysize = vrt_ds.GetRasterBand(1).GetBlockSize() + assert blockxsize == 32 + assert blockysize == 48 + vrt_ds = None + + gdal.Unlink(filename) + + +############################################################################### +# Test setting block size through creation options + + def test_vrtmisc_blocksize_gdal_translate_indirect(): filename = "/vsimem/test_vrtmisc_blocksize_gdal_translate_indirect.vrt" vrt_ds = gdal.Translate( @@ -1078,3 +1088,13 @@ def test_vrt_read_netcdf(): xml_data = xml.read() # print(xml_data) assert 'NETCDF:"alldatatypes.nc":ubyte_var' in xml_data + + +############################################################################### + + +def test_vrtmisc_add_band_gdt_unknown(): + vrt_ds = gdal.GetDriverByName("VRT").Create("", 1, 1, 0) + options = ["subClass=VRTSourcedRasterBand", "blockXSize=32", "blockYSize=48"] + with pytest.raises(Exception, match="Illegal GDT_Unknown/GDT_TypeCount argument"): + vrt_ds.AddBand(gdal.GDT_Unknown, options) diff --git a/autotest/gcore/vsi7z.py b/autotest/gcore/vsi7z.py index d1bfcd47a240..105332cbbbf9 100755 --- a/autotest/gcore/vsi7z.py +++ b/autotest/gcore/vsi7z.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/vsiadls.py b/autotest/gcore/vsiadls.py index 11f3a6ea56a8..cc61c8f38c6d 100755 --- a/autotest/gcore/vsiadls.py +++ b/autotest/gcore/vsiadls.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/gcore/vsiadls_real_instance.py b/autotest/gcore/vsiadls_real_instance.py index b377f23d26be..d61996a3edfc 100755 --- a/autotest/gcore/vsiadls_real_instance.py +++ b/autotest/gcore/vsiadls_real_instance.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020 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. +# SPDX-License-Identifier: MIT ############################################################################### import base64 diff --git a/autotest/gcore/vsiaz.py b/autotest/gcore/vsiaz.py index 60701a3c7742..348f794b44dd 100755 --- a/autotest/gcore/vsiaz.py +++ b/autotest/gcore/vsiaz.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017 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. +# SPDX-License-Identifier: MIT ############################################################################### import copy @@ -453,6 +437,10 @@ def test_vsiaz_sas_fake(): # Test write +@pytest.mark.skipif( + "CI" in os.environ, + reason="Flaky", +) def test_vsiaz_fake_write(): if gdaltest.webserver_port == 0: diff --git a/autotest/gcore/vsiaz_real_instance_auto.py b/autotest/gcore/vsiaz_real_instance_auto.py index 10575652f58f..43d88e4f5067 100644 --- a/autotest/gcore/vsiaz_real_instance_auto.py +++ b/autotest/gcore/vsiaz_real_instance_auto.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/vsiaz_real_instance_manual.py b/autotest/gcore/vsiaz_real_instance_manual.py index 26e2738bebb7..b29fb576db60 100644 --- a/autotest/gcore/vsiaz_real_instance_manual.py +++ b/autotest/gcore/vsiaz_real_instance_manual.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017 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. +# SPDX-License-Identifier: MIT ############################################################################### import stat diff --git a/autotest/gcore/vsicached.py b/autotest/gcore/vsicached.py index 4fd41b389e7f..b526493c5506 100755 --- a/autotest/gcore/vsicached.py +++ b/autotest/gcore/vsicached.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/vsicrypt.py b/autotest/gcore/vsicrypt.py index 391b8b5d69db..6ac558599173 100755 --- a/autotest/gcore/vsicrypt.py +++ b/autotest/gcore/vsicrypt.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ctypes diff --git a/autotest/gcore/vsicurl.py b/autotest/gcore/vsicurl.py index 45746a20f57b..305641d1d1ca 100755 --- a/autotest/gcore/vsicurl.py +++ b/autotest/gcore/vsicurl.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys @@ -233,11 +217,204 @@ def server(): webserver.server_stop(process, port) +############################################################################### +# Test regular redirection + + +@pytest.mark.parametrize( + "authorization_header_allowed", [None, "YES", "NO", "IF_SAME_HOST"] +) +def test_vsicurl_test_redirect(server, authorization_header_allowed): + + gdal.VSICurlClearCache() + + expected_headers = None + unexpected_headers = [] + if authorization_header_allowed != "NO": + expected_headers = {"Authorization": "Bearer xxx"} + else: + unexpected_headers = ["Authorization"] + + handler = webserver.SequentialHandler() + handler.add("GET", "/test_redirect/", 404) + handler.add( + "HEAD", + "/test_redirect/test.bin", + 301, + {"Location": "http://localhost:%d/redirected/test.bin" % server.port}, + expected_headers={"Authorization": "Bearer xxx"}, + ) + + # Curl always forward Authorization if same server when handling itself + # the redirect, so this means that CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT=NO + # is not honored for that particular request. To honour it, we would have + # to disable CURLOPT_FOLLOWLOCATION and implement it at hand + handler.add( + "HEAD", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + expected_headers={"Authorization": "Bearer xxx"}, + ) + + handler.add( + "GET", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + b"xyz", + expected_headers=expected_headers, + unexpected_headers=unexpected_headers, + ) + + options = {"GDAL_HTTP_HEADERS": "Authorization: Bearer xxx"} + if authorization_header_allowed: + options[ + "CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT" + ] = authorization_header_allowed + with webserver.install_http_handler(handler), gdal.config_options(options): + f = gdal.VSIFOpenL( + "/vsicurl/http://localhost:%d/test_redirect/test.bin" % server.port, + "rb", + ) + assert f is not None + try: + assert gdal.VSIFReadL(1, 3, f) == b"xyz" + finally: + gdal.VSIFCloseL(f) + + +############################################################################### +# Test regular redirection + + +@pytest.mark.parametrize( + "authorization_header_allowed", [None, "YES", "NO", "IF_SAME_HOST"] +) +def test_vsicurl_test_redirect_different_server(server, authorization_header_allowed): + + gdal.VSICurlClearCache() + + expected_headers = None + unexpected_headers = [] + if authorization_header_allowed == "YES": + expected_headers = {"Authorization": "Bearer xxx"} + else: + unexpected_headers = ["Authorization"] + + handler = webserver.SequentialHandler() + handler.add("GET", "/test_redirect/", 404) + handler.add( + "HEAD", + "/test_redirect/test.bin", + 301, + {"Location": "http://127.0.0.1:%d/redirected/test.bin" % server.port}, + expected_headers={"Authorization": "Bearer xxx"}, + ) + handler.add( + "HEAD", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + expected_headers=expected_headers, + unexpected_headers=unexpected_headers, + ) + handler.add( + "GET", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + b"xyz", + expected_headers=expected_headers, + unexpected_headers=unexpected_headers, + ) + + options = {"GDAL_HTTP_HEADERS": "Authorization: Bearer xxx"} + if authorization_header_allowed: + options[ + "CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT" + ] = authorization_header_allowed + with webserver.install_http_handler(handler), gdal.config_options(options): + f = gdal.VSIFOpenL( + "/vsicurl/http://localhost:%d/test_redirect/test.bin" % server.port, + "rb", + ) + try: + assert gdal.VSIFReadL(1, 3, f) == b"xyz" + finally: + gdal.VSIFCloseL(f) + + +############################################################################### +# Test regular redirection + + +@gdaltest.enable_exceptions() +@pytest.mark.require_curl(7, 61, 0) +@pytest.mark.parametrize( + "authorization_header_allowed", [None, "YES", "NO", "IF_SAME_HOST"] +) +def test_vsicurl_test_redirect_different_server_with_bearer( + server, authorization_header_allowed +): + + gdal.VSICurlClearCache() + + expected_headers = None + unexpected_headers = [] + if authorization_header_allowed == "YES": + expected_headers = {"Authorization": "Bearer xxx"} + else: + unexpected_headers = ["Authorization"] + + handler = webserver.SequentialHandler() + handler.add("GET", "/test_redirect/", 404) + handler.add( + "HEAD", + "/test_redirect/test.bin", + 301, + {"Location": "http://127.0.0.1:%d/redirected/test.bin" % server.port}, + expected_headers={"Authorization": "Bearer xxx"}, + ) + handler.add( + "HEAD", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + expected_headers=expected_headers, + unexpected_headers=unexpected_headers, + ) + handler.add( + "GET", + "/redirected/test.bin", + 200, + {"Content-Length": "3"}, + b"xyz", + expected_headers=expected_headers, + unexpected_headers=unexpected_headers, + ) + + options = {"GDAL_HTTP_AUTH": "BEARER", "GDAL_HTTP_BEARER": "xxx"} + if authorization_header_allowed: + options[ + "CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT" + ] = authorization_header_allowed + with webserver.install_http_handler(handler), gdal.config_options(options): + f = gdal.VSIFOpenL( + "/vsicurl/http://localhost:%d/test_redirect/test.bin" % server.port, + "rb", + ) + try: + assert gdal.VSIFReadL(1, 3, f) == b"xyz" + finally: + gdal.VSIFCloseL(f) + + ############################################################################### # Test redirection with Expires= type of signed URLs -def test_vsicurl_test_redirect(server): +def test_vsicurl_test_redirect_with_expires(server): gdal.VSICurlClearCache() diff --git a/autotest/gcore/vsicurl_streaming.py b/autotest/gcore/vsicurl_streaming.py index cf44eed9548e..d3ded6ed2d3a 100755 --- a/autotest/gcore/vsicurl_streaming.py +++ b/autotest/gcore/vsicurl_streaming.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import threading diff --git a/autotest/gcore/vsifile.py b/autotest/gcore/vsifile.py index fe96a8b808c4..12b69d9eaca7 100755 --- a/autotest/gcore/vsifile.py +++ b/autotest/gcore/vsifile.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -150,6 +134,26 @@ def vsifile_generic(filename, options=[]): gdal.Unlink(filename) + if not filename.startswith("/vsicrypt/"): + assert gdal.RmdirRecursive(filename + "/i_dont_exist") == -1 + + subdir = filename + "/subdir" + assert gdal.MkdirRecursive(subdir + "/subsubdir", 0o755) == 0 + + assert gdal.VSIStatL(subdir) is not None + assert gdal.VSIStatL(subdir + "/subsubdir") is not None + + if not filename.startswith("/vsimem/"): + assert gdal.Rmdir(subdir) == -1 + assert gdal.VSIStatL(subdir) is not None + + # Safety belt... + assert filename.startswith("tmp/") or filename.startswith("/vsimem/") + assert gdal.RmdirRecursive(filename) == 0 + + assert gdal.VSIStatL(subdir) is None + assert gdal.VSIStatL(subdir + "/subsubdir") is None + ############################################################################### # Test /vsimem @@ -233,16 +237,16 @@ def test_vsifile_4(): # Test vsicache -@pytest.mark.parametrize("cache_size", ("0", "65536", None)) -def test_vsifile_5(cache_size): +@pytest.mark.parametrize("cache_size", ("0", "64kb", None)) +def test_vsifile_5(tmp_path, cache_size): - fp = gdal.VSIFOpenL("tmp/vsifile_5.bin", "wb") + fp = gdal.VSIFOpenL(tmp_path / "vsifile_5.bin", "wb") ref_data = "".join(["%08X" % i for i in range(5 * 32768)]) gdal.VSIFWriteL(ref_data, 1, len(ref_data), fp) gdal.VSIFCloseL(fp) with gdal.config_options({"VSI_CACHE": "YES", "VSI_CACHE_SIZE": cache_size}): - fp = gdal.VSIFOpenL("tmp/vsifile_5.bin", "rb") + fp = gdal.VSIFOpenL(tmp_path / "vsifile_5.bin", "rb") gdal.VSIFSeekL(fp, 50000, 0) if gdal.VSIFTellL(fp) != 50000: @@ -273,8 +277,6 @@ def test_vsifile_5(cache_size): gdal.VSIFCloseL(fp) - gdal.Unlink("tmp/vsifile_5.bin") - ############################################################################### # Test vsicache an read errors (https://github.com/qgis/QGIS/issues/45293) @@ -681,6 +683,15 @@ def test_vsifile_14(): ) +############################################################################### +# Test bugfix for https://github.com/OSGeo/gdal/issues/10821 + + +def test_vsifile_vsitar_of_vsitar(): + + gdal.Open("/vsitar/{/vsitar/data/tar_of_tar_gzip.tar}/byte_tif.tar.gz/byte.tif") + + ############################################################################### # Test issue with Error() not detecting end of corrupted gzip stream (#6944) @@ -776,12 +787,8 @@ def test_vsifile_19(): def test_vsifile_20(): - try: + with pytest.raises(Exception): gdal.VSIFReadL(1, 1, None) - except ValueError: - return - - pytest.fail() ############################################################################### @@ -1710,7 +1717,7 @@ def test_vsifile_MultipartUpload(): with gdal.quiet_errors(): assert gdal.MultipartUploadGetCapabilities("foo") is None with gdal.ExceptionMgr(useExceptions=True): - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadGetCapabilities(None) with pytest.raises( @@ -1719,7 +1726,7 @@ def test_vsifile_MultipartUpload(): ): gdal.MultipartUploadGetCapabilities("foo") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadStart(None) with pytest.raises( @@ -1728,9 +1735,9 @@ def test_vsifile_MultipartUpload(): ): gdal.MultipartUploadStart("foo") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadAddPart(None, "", 1, 0, b"") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadAddPart("", None, 1, 0, b"") with pytest.raises( @@ -1739,9 +1746,9 @@ def test_vsifile_MultipartUpload(): ): gdal.MultipartUploadAddPart("", "", 1, 0, b"") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadEnd(None, "", [], 0) - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadEnd("", None, [], 0) with pytest.raises( @@ -1750,9 +1757,9 @@ def test_vsifile_MultipartUpload(): ): gdal.MultipartUploadEnd("", "", [], 0) - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadAbort(None, "") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.MultipartUploadAbort("", None) with pytest.raises( diff --git a/autotest/gcore/vsigs.py b/autotest/gcore/vsigs.py index f619f79a779f..dd78ab9cffc2 100755 --- a/autotest/gcore/vsigs.py +++ b/autotest/gcore/vsigs.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017 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. +# SPDX-License-Identifier: MIT ############################################################################### import stat @@ -708,6 +692,107 @@ def test_vsigs_headers(gs_test_config, webserver_port): ) +############################################################################### +# Test GetFileMetadata() on root of bucket with OAuth2 + + +@gdaltest.enable_exceptions() +def test_vsigs_GetFileMetadatabucket_root_oauth2( + gs_test_config, webserver_port, tmp_vsimem +): + + gdal.VSICurlClearCache() + + service_account_filename = str(tmp_vsimem / "service_account.json") + gdal.FileFromMemBuffer( + service_account_filename, + """{ + "private_key": "-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOlwJQLLDG1HeLrk\nVNcFR5Qptto/rJE5emRuy0YmkVINT4uHb1be7OOo44C2Ev8QPVtNHHS2XwCY5gTm\ni2RfIBLv+VDMoVQPqqE0LHb0WeqGmM5V1tHbmVnIkCcKMn3HpK30grccuBc472LQ\nDVkkGqIiGu0qLAQ89JP/r0LWWySRAgMBAAECgYAWjsS00WRBByAOh1P/dz4kfidy\nTabiXbiLDf3MqJtwX2Lpa8wBjAc+NKrPXEjXpv0W3ou6Z4kkqKHJpXGg4GRb4N5I\n2FA+7T1lA0FCXa7dT2jvgJLgpBepJu5b//tqFqORb4A4gMZw0CiPN3sUsWsSw5Hd\nDrRXwp6sarzG77kvZQJBAPgysAmmXIIp9j1hrFSkctk4GPkOzZ3bxKt2Nl4GFrb+\nbpKSon6OIhP1edrxTz1SMD1k5FiAAVUrMDKSarbh5osCQQDwxq4Tvf/HiYz79JBg\nWz5D51ySkbg01dOVgFW3eaYAdB6ta/o4vpHhnbrfl6VO9oUb3QR4hcrruwnDHsw3\n4mDTAkEA9FPZjbZSTOSH/cbgAXbdhE4/7zWOXj7Q7UVyob52r+/p46osAk9i5qj5\nKvnv2lrFGDrwutpP9YqNaMtP9/aLnwJBALLWf9n+GAv3qRZD0zEe1KLPKD1dqvrj\nj+LNjd1Xp+tSVK7vMs4PDoAMDg+hrZF3HetSQM3cYpqxNFEPgRRJOy0CQQDQlZHI\nyzpSgEiyx8O3EK1iTidvnLXbtWabvjZFfIE/0OhfBmN225MtKG3YLV2HoUvpajLq\ngwE6fxOLyJDxuWRf\n-----END PRIVATE KEY-----\n", + "client_email": "CLIENT_EMAIL", + "type": "service_account" + }""", + ) + + gdal.SetPathSpecificOption( + "/vsigs/gs_fake_bucket", + "GOOGLE_APPLICATION_CREDENTIALS", + service_account_filename, + ) + + try: + with gdaltest.config_options( + { + "GO2A_AUD": "http://localhost:%d/oauth2/v4/token" % webserver_port, + "GOA2_NOW": "123456", + }, + thread_local=False, + ): + + gdal.VSICurlClearCache() + + handler = webserver.SequentialHandler() + + def method(request): + request.send_response(200) + request.send_header("Content-type", "text/plain") + content = """{ + "access_token" : "ACCESS_TOKEN", + "token_type" : "Bearer", + "expires_in" : 3600, + }""" + request.send_header("Content-Length", len(content)) + request.end_headers() + request.wfile.write(content.encode("ascii")) + + handler.add("POST", "/oauth2/v4/token", custom_method=method) + + handler.add( + "GET", + "/storage/v1/b/gs_fake_bucket", + 200, + {"Content-type": "application/json"}, + '{"foo":"bar"}', + ) + try: + with webserver.install_http_handler(handler): + md = gdal.GetFileMetadata("/vsigs/gs_fake_bucket/", None) + + except Exception: + if ( + gdal.GetLastErrorMsg().find("CPLRSASHA256Sign() not implemented") + >= 0 + ): + pytest.skip("CPLRSASHA256Sign() not implemented") + + assert md == {"foo": "bar"} + finally: + gdal.SetPathSpecificOption( + "/vsigs/gs_fake_bucket", "GOOGLE_APPLICATION_CREDENTIALS", None + ) + + +############################################################################### +# Test GetFileMetadata() on root of bucket with non-OAuth2 (does not work) + + +def test_vsigs_GetFileMetadatabucket_root_not_oauth2(gs_test_config, webserver_port): + + gdal.VSICurlClearCache() + + with gdaltest.config_options( + { + "GS_SECRET_ACCESS_KEY": "GS_SECRET_ACCESS_KEY", + "GS_ACCESS_KEY_ID": "GS_ACCESS_KEY_ID", + }, + thread_local=False, + ): + + handler = webserver.SequentialHandler() + with webserver.install_http_handler(handler): + md = gdal.GetFileMetadata("/vsigs/gs_fake_bucket/", None) + assert md == {} + + ############################################################################### # Read credentials with OAuth2 refresh_token diff --git a/autotest/gcore/vsihdfs.py b/autotest/gcore/vsihdfs.py index c44c31326798..755477082728 100755 --- a/autotest/gcore/vsihdfs.py +++ b/autotest/gcore/vsihdfs.py @@ -11,23 +11,7 @@ # Copyright (c) 2011-2013, Even Rouault # Copyright (c) 2018, Azavea # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/vsioss.py b/autotest/gcore/vsioss.py index be75e9506ce5..7dda14517f16 100755 --- a/autotest/gcore/vsioss.py +++ b/autotest/gcore/vsioss.py @@ -9,25 +9,10 @@ ############################################################################### # Copyright (c) 2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import os import stat import sys @@ -841,7 +826,8 @@ def test_vsioss_5(server): @pytest.mark.skipif( - gdaltest.is_travis_branch("macos_build"), reason="randomly fails on macos" + "CI" in os.environ, + reason="Flaky", ) @gdaltest.disable_exceptions() def test_vsioss_6(server): diff --git a/autotest/gcore/vsipathspecificoption.py b/autotest/gcore/vsipathspecificoption.py index 75b45568ae47..9b1182bdf529 100755 --- a/autotest/gcore/vsipathspecificoption.py +++ b/autotest/gcore/vsipathspecificoption.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gcore/vsirar.py b/autotest/gcore/vsirar.py index efe775f2fa08..6710b95848df 100755 --- a/autotest/gcore/vsirar.py +++ b/autotest/gcore/vsirar.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gcore/vsis3.py b/autotest/gcore/vsis3.py index 2392acdaecda..77cbbee6a6ef 100755 --- a/autotest/gcore/vsis3.py +++ b/autotest/gcore/vsis3.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -909,7 +893,7 @@ def method(request): # Test temporary redirect handler = webserver.SequentialHandler() - class HandlerClass(object): + class HandlerClass: def __init__(self, response_value): self.old_authorization = None self.response_value = response_value @@ -1500,7 +1484,7 @@ def method(request): # Test temporary redirect handler = webserver.SequentialHandler() - class HandlerClass(object): + class HandlerClass: def __init__(self, response_value): self.old_authorization = None self.response_value = response_value @@ -6109,6 +6093,121 @@ def test_vsis3_read_credentials_sts_assume_role_with_web_identity_from_config_fi assert data == "foo" +############################################################################### +# Read credentials from cached SSO file + + +def test_vsis3_read_credentials_sso(tmp_vsimem, aws_test_config, webserver_port): + + if webserver_port != 8080: + pytest.skip("only works for webserver on port 8080") + + options = { + "AWS_SECRET_ACCESS_KEY": "", + "AWS_ACCESS_KEY_ID": "", + "AWS_PROFILE": "my_profile", + "CPL_AWS_SSO_ENDPOINT": "localhost:%d" % webserver_port, + "CPL_AWS_ROOT_DIR": str(tmp_vsimem), + } + + gdal.VSICurlClearCache() + + gdal.FileFromMemBuffer( + tmp_vsimem / "config", + """ +[sso-session my-sso] +sso_start_url = https://example.com +sso_region = eu-central-1 +sso_registration_scopes = sso:account:access + +[profile my_profile] +sso_session = my-sso +sso_account_id = my_sso_account_id +sso_role_name = my_sso_role_name +region = eu-east-1 +""", + ) + + gdal.FileFromMemBuffer( + tmp_vsimem / "sso" / "cache" / "327c3fda87ce286848a574982ddd0b7c7487f816.json", + '{"startUrl": "https://example.com", "region": "us-east-1", "accessToken": "sso-accessToken", "expiresAt": "9999-01-01T00:00:00Z"}', + ) + + gdal.VSICurlClearCache() + + handler = webserver.SequentialHandler() + + handler.add( + "GET", + "/federation/credentials?role_name=my_sso_role_name&account_id=my_sso_account_id", + 200, + {}, + """{ + "roleCredentials": { + "accessKeyId": "accessKeyId", + "secretAccessKey": "secretAccessKey", + "sessionToken": "sessionToken", + "expiration": 9999999999000 + } +}""", + expected_headers={ + "x-amz-sso_bearer_token": "sso-accessToken", + }, + ) + + handler.add( + "GET", + "/s3_fake_bucket/resource", + 200, + {}, + """foo""", + expected_headers={ + "x-amz-date": "20150101T000000Z", + "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "X-Amz-Security-Token": "sessionToken", + "Authorization": "AWS4-HMAC-SHA256 Credential=accessKeyId/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token,Signature=bfa9fb8c88286e3ef6537303784efe45721ede5e5bf51091565a66cf1ad8084a", + }, + ) + + with webserver.install_http_handler(handler): + with gdaltest.config_options(options, thread_local=False): + f = open_for_read("/vsis3/s3_fake_bucket/resource") + assert f is not None + try: + data = gdal.VSIFReadL(1, 4, f).decode("ascii") + finally: + gdal.VSIFCloseL(f) + + assert data == "foo" + + handler = webserver.SequentialHandler() + + handler.add( + "GET", + "/s3_fake_bucket/resource2", + 200, + {}, + """bar""", + expected_headers={ + "x-amz-date": "20150101T000000Z", + "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "X-Amz-Security-Token": "sessionToken", + "Authorization": "AWS4-HMAC-SHA256 Credential=accessKeyId/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token,Signature=b081c4f3195807de3fc934626f7ef7f3fd8e1143226bcbf2afce478c4bb7d4ff", + }, + ) + + with webserver.install_http_handler(handler): + with gdaltest.config_options(options, thread_local=False): + f = open_for_read("/vsis3/s3_fake_bucket/resource2") + assert f is not None + try: + data = gdal.VSIFReadL(1, 4, f).decode("ascii") + finally: + gdal.VSIFCloseL(f) + + assert data == "bar" + + ############################################################################### diff --git a/autotest/gcore/vsistdin.py b/autotest/gcore/vsistdin.py index 1e68741873f3..d7c0b6780d1f 100755 --- a/autotest/gcore/vsistdin.py +++ b/autotest/gcore/vsistdin.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -108,6 +92,10 @@ def test_vsistdin_3(): # Test fix for #6061 +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_vsistdin_4(): if test_cli_utilities.get_gdal_translate_path() is None: pytest.skip() diff --git a/autotest/gcore/vsiswift.py b/autotest/gcore/vsiswift.py index 0766a731b607..8b239cc1fddd 100755 --- a/autotest/gcore/vsiswift.py +++ b/autotest/gcore/vsiswift.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2018 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/gcore/vsiwebhdfs.py b/autotest/gcore/vsiwebhdfs.py index 0f99d075f42d..28403e113e3a 100755 --- a/autotest/gcore/vsiwebhdfs.py +++ b/autotest/gcore/vsiwebhdfs.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2018 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. +# SPDX-License-Identifier: MIT ############################################################################### import stat diff --git a/autotest/gcore/vsizip.py b/autotest/gcore/vsizip.py index d28765150af6..8942fc4f42ff 100755 --- a/autotest/gcore/vsizip.py +++ b/autotest/gcore/vsizip.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import random diff --git a/autotest/gdrivers/aaigrid.py b/autotest/gdrivers/aaigrid.py index 8c1fb3f79854..77fbf5e935a8 100755 --- a/autotest/gdrivers/aaigrid.py +++ b/autotest/gdrivers/aaigrid.py @@ -12,23 +12,7 @@ # Copyright (c) 2008-2010, Even Rouault # Copyright (c) 2014, Kyle Shannon # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -236,6 +220,10 @@ def test_aaigrid_6bis(): # Verify writing files with non-square pixels. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_aaigrid_7(): tst = gdaltest.GDALTest("AAIGRID", "aaigrid/nonsquare.vrt", 1, 12481) diff --git a/autotest/gdrivers/ace2.py b/autotest/gdrivers/ace2.py index 9d34783c84bd..ad3a194ff6d2 100755 --- a/autotest/gdrivers/ace2.py +++ b/autotest/gdrivers/ace2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/adrg.py b/autotest/gdrivers/adrg.py index 9ec5299d9852..3fe1ead3e2b4 100755 --- a/autotest/gdrivers/adrg.py +++ b/autotest/gdrivers/adrg.py @@ -10,23 +10,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2007-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/aigrid.py b/autotest/gdrivers/aigrid.py index a6d757a0b88f..c68ef8545abd 100755 --- a/autotest/gdrivers/aigrid.py +++ b/autotest/gdrivers/aigrid.py @@ -10,23 +10,7 @@ # Copyright (c) 2006, Swapnil Hajare # Copyright (c) 2009-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/avif.py b/autotest/gdrivers/avif.py index 0e42ca88e00c..140ce6d43a50 100644 --- a/autotest/gdrivers/avif.py +++ b/autotest/gdrivers/avif.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import base64 diff --git a/autotest/gdrivers/avif_heif.py b/autotest/gdrivers/avif_heif.py index 3d549f5e1752..42af055418ea 100755 --- a/autotest/gdrivers/avif_heif.py +++ b/autotest/gdrivers/avif_heif.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/bag.py b/autotest/gdrivers/bag.py index b08119b6ca85..4a4adfdf3cfc 100755 --- a/autotest/gdrivers/bag.py +++ b/autotest/gdrivers/bag.py @@ -11,23 +11,7 @@ # Copyright (c) 2010-2013, Even Rouault # Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/basisu.py b/autotest/gdrivers/basisu.py index a24f06cd2d20..2d5c28d5b125 100755 --- a/autotest/gdrivers/basisu.py +++ b/autotest/gdrivers/basisu.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/blx.py b/autotest/gdrivers/blx.py index c8b20d6b239a..f84c4caffb06 100755 --- a/autotest/gdrivers/blx.py +++ b/autotest/gdrivers/blx.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/bsb.py b/autotest/gdrivers/bsb.py index 49efd4fc3b08..b62d129311d6 100755 --- a/autotest/gdrivers/bsb.py +++ b/autotest/gdrivers/bsb.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/bt.py b/autotest/gdrivers/bt.py index f058908c9789..8a7233a4bf27 100755 --- a/autotest/gdrivers/bt.py +++ b/autotest/gdrivers/bt.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/byn.py b/autotest/gdrivers/byn.py index 51378c7c8970..39edc2e85463 100755 --- a/autotest/gdrivers/byn.py +++ b/autotest/gdrivers/byn.py @@ -11,23 +11,7 @@ # Copyright (c) 2018, Ivan Lucena # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/cals.py b/autotest/gdrivers/cals.py index d6e7693c420b..b562d23b3d00 100755 --- a/autotest/gdrivers/cals.py +++ b/autotest/gdrivers/cals.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/ceos.py b/autotest/gdrivers/ceos.py index 44a77a330914..57446e45b8d6 100755 --- a/autotest/gdrivers/ceos.py +++ b/autotest/gdrivers/ceos.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/cpg.py b/autotest/gdrivers/cpg.py index 174b37a0d0ba..2efca291d71c 100755 --- a/autotest/gdrivers/cpg.py +++ b/autotest/gdrivers/cpg.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/ctg.py b/autotest/gdrivers/ctg.py index aef69343965c..611b232d2361 100755 --- a/autotest/gdrivers/ctg.py +++ b/autotest/gdrivers/ctg.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/daas.py b/autotest/gdrivers/daas.py index f1251de83447..c2abeb58d32c 100755 --- a/autotest/gdrivers/daas.py +++ b/autotest/gdrivers/daas.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018-2019, Airbus DS Intelligence # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import copy diff --git a/autotest/gdrivers/daas_real_instance.py b/autotest/gdrivers/daas_real_instance.py index dc51de11bd90..ffa99a86f464 100755 --- a/autotest/gdrivers/daas_real_instance.py +++ b/autotest/gdrivers/daas_real_instance.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2021, Airbus DS Intelligence # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/data/bag/generate_test_georef_metadata.py b/autotest/gdrivers/data/bag/generate_test_georef_metadata.py index a03e77f697a4..03ac88cf9bed 100755 --- a/autotest/gdrivers/data/bag/generate_test_georef_metadata.py +++ b/autotest/gdrivers/data/bag/generate_test_georef_metadata.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/data/bag/generate_test_interpolated.py b/autotest/gdrivers/data/bag/generate_test_interpolated.py index ebc8257db026..09af6bb9e4e8 100755 --- a/autotest/gdrivers/data/bag/generate_test_interpolated.py +++ b/autotest/gdrivers/data/bag/generate_test_interpolated.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/data/heif/uncompressed_comp_RGB_tiled.heif b/autotest/gdrivers/data/heif/uncompressed_comp_RGB_tiled.heif new file mode 100644 index 000000000000..ab30d7f2113c Binary files /dev/null and b/autotest/gdrivers/data/heif/uncompressed_comp_RGB_tiled.heif differ diff --git a/autotest/gdrivers/data/jpeg2000/byte_lossless_openjp2_golden.jp2 b/autotest/gdrivers/data/jpeg2000/byte_lossless_openjp2_golden.jp2 new file mode 100644 index 000000000000..049871c52ec8 Binary files /dev/null and b/autotest/gdrivers/data/jpeg2000/byte_lossless_openjp2_golden.jp2 differ diff --git a/autotest/gdrivers/data/jpegxl/float16.jxl b/autotest/gdrivers/data/jpegxl/float16.jxl new file mode 100644 index 000000000000..7a60b5a41fe9 Binary files /dev/null and b/autotest/gdrivers/data/jpegxl/float16.jxl differ diff --git a/autotest/gdrivers/data/netcdf/byte_nc3_golden.nc b/autotest/gdrivers/data/netcdf/byte_nc3_golden.nc new file mode 100644 index 000000000000..09b43e1a71fb Binary files /dev/null and b/autotest/gdrivers/data/netcdf/byte_nc3_golden.nc differ diff --git a/autotest/gdrivers/data/pdf/invalid_srs.pdf b/autotest/gdrivers/data/pdf/invalid_srs.pdf new file mode 100644 index 000000000000..7f1f0b3628e4 Binary files /dev/null and b/autotest/gdrivers/data/pdf/invalid_srs.pdf differ diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VH.tif b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VH.tif new file mode 100644 index 000000000000..0a4a9c098f4b Binary files /dev/null and b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VH.tif differ diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VV.tif b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VV.tif new file mode 100644 index 000000000000..0a4a9c098f4b Binary files /dev/null and b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/imagery/VV.tif differ diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/manifest.safe b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/manifest.safe new file mode 100644 index 000000000000..ba158aceab12 --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/manifest.safe @@ -0,0 +1,4 @@ + + + + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/incidenceAngles.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/incidenceAngles.xml new file mode 100644 index 000000000000..4bddbd3a0dde --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/incidenceAngles.xml @@ -0,0 +1,7 @@ + + + 0 + -23 + 1 + 0 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VH.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VH.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VH.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VV.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VV.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VV.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VH.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VH.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VH.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VV.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VV.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VV.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VH.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VH.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VH.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VV.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VV.xml new file mode 100644 index 000000000000..cd3967c9d87a --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VV.xml @@ -0,0 +1,8 @@ + + + 10 + -17915 + 1 + 0 + 10 + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VH.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VH.xml new file mode 100644 index 000000000000..50f5d4426e23 --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VH.xml @@ -0,0 +1,264 @@ + + + + Beta Nought + 0 + -23 + 1 + 0 + + + Sigma Nought + 0 + -23 + 1 + 0 + + + Gamma + 0 + -23 + 1 + 0 + + + SC-5 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-6 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-7 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-8 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-9 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-10 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-11 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-12 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-5 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-6 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-7 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-8 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-9 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-10 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-11 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-12 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-5 + Gamma + 0 + -3 + 1 + 0 + + + SC-6 + Gamma + 0 + -3 + 1 + 0 + + + SC-7 + Gamma + 0 + -3 + 1 + 0 + + + SC-8 + Gamma + 0 + -3 + 1 + 0 + + + SC-9 + Gamma + 0 + -3 + 1 + 0 + + + SC-10 + Gamma + 0 + -3 + 1 + 0 + + + SC-11 + Gamma + 0 + -3 + 1 + 0 + + + SC-12 + Gamma + 0 + -3 + 1 + 0 + + + SC-5 + 1 + 1 + 0 + + + SC-6 + 1 + 1 + 0 + + + SC-7 + 1 + 1 + 0 + + + SC-8 + 1 + 1 + 0 + + + SC-9 + 1 + 1 + 0 + + + SC-10 + 1 + 1 + 0 + + + SC-11 + 1 + 1 + 0 + + + SC-12 + 1 + 1 + 0 + + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VV.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VV.xml new file mode 100644 index 000000000000..50f5d4426e23 --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/calibration/noiseLevels_VV.xml @@ -0,0 +1,264 @@ + + + + Beta Nought + 0 + -23 + 1 + 0 + + + Sigma Nought + 0 + -23 + 1 + 0 + + + Gamma + 0 + -23 + 1 + 0 + + + SC-5 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-6 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-7 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-8 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-9 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-10 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-11 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-12 + Beta Nought + 0 + -3 + 1 + 0 + + + SC-5 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-6 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-7 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-8 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-9 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-10 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-11 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-12 + Sigma Nought + 0 + -3 + 1 + 0 + + + SC-5 + Gamma + 0 + -3 + 1 + 0 + + + SC-6 + Gamma + 0 + -3 + 1 + 0 + + + SC-7 + Gamma + 0 + -3 + 1 + 0 + + + SC-8 + Gamma + 0 + -3 + 1 + 0 + + + SC-9 + Gamma + 0 + -3 + 1 + 0 + + + SC-10 + Gamma + 0 + -3 + 1 + 0 + + + SC-11 + Gamma + 0 + -3 + 1 + 0 + + + SC-12 + Gamma + 0 + -3 + 1 + 0 + + + SC-5 + 1 + 1 + 0 + + + SC-6 + 1 + 1 + 0 + + + SC-7 + 1 + 1 + 0 + + + SC-8 + 1 + 1 + 0 + + + SC-9 + 1 + 1 + 0 + + + SC-10 + 1 + 1 + 0 + + + SC-11 + 1 + 1 + 0 + + + SC-12 + 1 + 1 + 0 + + diff --git a/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/product.xml b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/product.xml new file mode 100644 index 000000000000..a76707260d63 --- /dev/null +++ b/autotest/gdrivers/data/rcm/fake_VV_VH_GRD/metadata/product.xml @@ -0,0 +1,177 @@ + + + + productId + productAnnotation + productApplication + documentIdentifier + + Non classifié / Unclassified + false + specialHandlingInstructions + + + RCM-1 + SAR + Dual Co/Cross + downlinkSegmentId + inputDatasetFacilityId + Medium Resolution 50m + beamModeDefinitionId + beamModeVersion + beamModeMnemonic + rawDataStartTime + + Medium Resolution 50m + beams + VH VV + + + + + + Descending + Downlinked + true + orbitDataFileName + + + + + + + + GRD + VV VH + processingFacility + processingTime + softwareVersion + Expedited + + + Mixed + true + false + true + true + true + false + true + true + true + Nominal Chirp + 0.000000000000000e+00 + Adaptive Analysis + false + true + zeroDopplerTimeFirstLine + zeroDopplerTimeLastLine + 19633 + 19633 + 4 + rangeLookBandwidth + totalProcessedRangeBandwidth + true + + + + 1 + + + + + 600000 + + + + + + + GeoTIFF + BSQ + lutBeta_VV.xml + lutSigma_VV.xml + lutGamma_VV.xml + lutBeta_VH.xml + lutSigma_VH.xml + lutGamma_VH.xml + incidenceAngles.xml + noiseLevels_VV.xml + noiseLevels_VH.xml + + Magnitude Detected + Integer + 16 + sampledPixelSpacing + sampledLineSpacing + sampledPixelSpacingTime + sampledLineSpacingTime + Increasing + Decreasing + + + + WGS 1984 + 6.378137000000000e+06 + 6.356752314245179e+06 + 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 + 200 + + + + + 1 + 2 + + + 1.5 + 2.5 + 3.5 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + 1 + + ../imagery/VV.tif + ../imagery/VH.tif + 0 + 0 + 3297 + 17915 + incAngNearRng + incAngFarRng + slantRangeNearEdge + slantRangeFarEdge + mean_VV + mean_VH + pole_VV + pole_VH + + + + + + diff --git a/autotest/gdrivers/data/s102/MD_test_s102_v3.0_with_QualityOfBathymetryCoverage.xml b/autotest/gdrivers/data/s102/MD_test_s102_v3.0_with_QualityOfBathymetryCoverage.xml new file mode 100644 index 000000000000..7d5c8daa45e2 --- /dev/null +++ b/autotest/gdrivers/data/s102/MD_test_s102_v3.0_with_QualityOfBathymetryCoverage.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/autotest/gdrivers/data/s102/generate_test.py b/autotest/gdrivers/data/s102/generate_test.py index c4d3f81a8ed3..d00b5c1581e4 100755 --- a/autotest/gdrivers/data/s102/generate_test.py +++ b/autotest/gdrivers/data/s102/generate_test.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -35,7 +19,13 @@ import numpy as np -def generate(filename, version, with_QualityOfSurvey=False): +def generate( + filename, + version, + with_QualityOfSurvey=False, + with_QualityOfCoverage=False, + use_compound_type_for_Quality=False, +): f = h5py.File(os.path.join(os.path.dirname(__file__), f"{filename}.h5"), "w") BathymetryCoverage = f.create_group("BathymetryCoverage") BathymetryCoverage_01 = BathymetryCoverage.create_group("BathymetryCoverage.01") @@ -71,7 +61,7 @@ def generate(filename, version, with_QualityOfSurvey=False): f.attrs["issueDate"] = "2023-12-31" f.attrs["geographicIdentifier"] = "Somewhere" f.attrs["verticalDatum"] = np.int16(12) - if version == "INT.IHO.S-102.2.2": + if version >= "INT.IHO.S-102.2.2": f.attrs["horizontalCRS"] = np.int32(4326) f.attrs["verticalCS"] = np.int32(6498) # Depth, metres, orientation down f.attrs["verticalCoordinateBase"] = np.int32(2) @@ -90,9 +80,12 @@ def generate(filename, version, with_QualityOfSurvey=False): b"" ) - if with_QualityOfSurvey: - QualityOfSurvey = f.create_group("QualityOfSurvey") - QualityOfSurvey_01 = QualityOfSurvey.create_group("QualityOfSurvey.01") + if with_QualityOfSurvey or with_QualityOfCoverage: + quality_name = ( + "QualityOfSurvey" if with_QualityOfSurvey else "QualityOfBathymetryCoverage" + ) + qualityGroup = f.create_group(quality_name) + quality01Group = qualityGroup.create_group(quality_name + ".01") for attr_name in ( "gridOriginLongitude", @@ -102,16 +95,26 @@ def generate(filename, version, with_QualityOfSurvey=False): "numPointsLongitudinal", "numPointsLatitudinal", ): - QualityOfSurvey_01.attrs[attr_name] = BathymetryCoverage_01.attrs[attr_name] - - Group_001 = QualityOfSurvey_01.create_group("Group_001") - - values = Group_001.create_dataset("values", (2, 3), dtype=np.uint32) - data = np.array( - [0, 1, 2, 1000000, 3, 2], - dtype=np.uint32, - ).reshape(values.shape) - values[...] = data + quality01Group.attrs[attr_name] = BathymetryCoverage_01.attrs[attr_name] + + Group_001 = quality01Group.create_group("Group_001") + + if use_compound_type_for_Quality: + # As found in product 102DE00CA22_UNC_MD.H5 + data_struct_type = np.dtype([("iD", "u4")]) + values = Group_001.create_dataset("values", (2, 3), dtype=data_struct_type) + data = np.array( + [(0), (1), (2), (1000000), (3), (2)], + dtype=data_struct_type, + ).reshape(values.shape) + values[...] = data + else: + values = Group_001.create_dataset("values", (2, 3), dtype=np.uint32) + data = np.array( + [0, 1, 2, 1000000, 3, 2], + dtype=np.uint32, + ).reshape(values.shape) + values[...] = data featureAttributeTable_struct_type = np.dtype( [ @@ -121,7 +124,7 @@ def generate(filename, version, with_QualityOfSurvey=False): ] ) - featureAttributeTable = QualityOfSurvey.create_dataset( + featureAttributeTable = qualityGroup.create_dataset( "featureAttributeTable", (5,), dtype=featureAttributeTable_struct_type ) @@ -137,7 +140,7 @@ def generate(filename, version, with_QualityOfSurvey=False): ) featureAttributeTable[...] = data - GroupFQualityOfSurvey_struct_type = np.dtype( + GroupFQuality_struct_type = np.dtype( [ ("code", "S16"), ("name", "S16"), @@ -149,12 +152,12 @@ def generate(filename, version, with_QualityOfSurvey=False): ("closure", "S16"), ] ) - GroupFQualityOfSurvey = group_f.create_dataset( - "QualityOfSurvey", (1,), dtype=GroupFQualityOfSurvey_struct_type + GroupFQuality = group_f.create_dataset( + quality_name, (1,), dtype=GroupFQuality_struct_type ) - GroupFQualityOfSurvey[...] = np.array( + GroupFQuality[...] = np.array( [("id", "", "", "0", "H5T_INTEGER", "1", "", "geSemiInterval")], - dtype=GroupFQualityOfSurvey_struct_type, + dtype=GroupFQuality_struct_type, ) @@ -166,3 +169,10 @@ def generate(filename, version, with_QualityOfSurvey=False): "INT.IHO.S-102.2.2", with_QualityOfSurvey=True, ) + +generate( + "test_s102_v3.0_with_QualityOfBathymetryCoverage", + "INT.IHO.S-102.3.0.0", + with_QualityOfCoverage=True, + use_compound_type_for_Quality=True, +) diff --git a/autotest/gdrivers/data/s102/test_s102_v3.0_with_QualityOfBathymetryCoverage.h5 b/autotest/gdrivers/data/s102/test_s102_v3.0_with_QualityOfBathymetryCoverage.h5 new file mode 100644 index 000000000000..8877ede735bb Binary files /dev/null and b/autotest/gdrivers/data/s102/test_s102_v3.0_with_QualityOfBathymetryCoverage.h5 differ diff --git a/autotest/gdrivers/data/s104/generate_test.py b/autotest/gdrivers/data/s104/generate_test.py index ff4ea7c9097e..8104232cde1b 100755 --- a/autotest/gdrivers/data/s104/generate_test.py +++ b/autotest/gdrivers/data/s104/generate_test.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/data/s111/generate_test.py b/autotest/gdrivers/data/s111/generate_test.py index 70c402484855..f7c13aa27e88 100755 --- a/autotest/gdrivers/data/s111/generate_test.py +++ b/autotest/gdrivers/data/s111/generate_test.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip b/autotest/gdrivers/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip new file mode 100644 index 000000000000..521325d7b95d Binary files /dev/null and b/autotest/gdrivers/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip differ diff --git a/autotest/gdrivers/data/zarr/generate_test_files.py b/autotest/gdrivers/data/zarr/generate_test_files.py index 23aedd82bdee..416d2d78d727 100644 --- a/autotest/gdrivers/data/zarr/generate_test_files.py +++ b/autotest/gdrivers/data/zarr/generate_test_files.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import lzma diff --git a/autotest/gdrivers/dds.py b/autotest/gdrivers/dds.py index c9c2c1d194ad..35771deeceb1 100644 --- a/autotest/gdrivers/dds.py +++ b/autotest/gdrivers/dds.py @@ -10,23 +10,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/derived.py b/autotest/gdrivers/derived.py index 00ef1e9ff98f..9d67fe14d896 100755 --- a/autotest/gdrivers/derived.py +++ b/autotest/gdrivers/derived.py @@ -9,29 +9,16 @@ ############################################################################### # Copyright (c) 2016, Julien Michel, # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### +import gdaltest import pytest from osgeo import gdal +pytestmark = pytest.mark.require_driver("Derived") + def test_derived_test1(): filename = "../gcore/data/cfloat64.tif" @@ -159,6 +146,12 @@ def test_derived_test3(): # Raster with zero band gdal.Open("DERIVED_SUBDATASET:LOGAMPLITUDE:data/hdf5/CSK_DGM.h5") + +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) +def test_derived_vrt_errors(): for function in [ "real", "imag", diff --git a/autotest/gdrivers/dimap.py b/autotest/gdrivers/dimap.py index 9758e256362d..6e3378512ac3 100755 --- a/autotest/gdrivers/dimap.py +++ b/autotest/gdrivers/dimap.py @@ -9,28 +9,13 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os import shutil +import gdaltest import pytest from osgeo import gdal @@ -41,6 +26,10 @@ # Open and verify a the GCPs and metadata. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_dimap_1(): shutil.copy("data/dimap/METADATA.DIM", "tmp") @@ -244,6 +233,14 @@ def test_dimap_2_vhr2020_ms_fs(): "Red Edge", "Deep Blue", ] + assert [ds.GetRasterBand(i + 1).GetColorInterpretation() for i in range(6)] == [ + gdal.GCI_RedBand, + gdal.GCI_GreenBand, + gdal.GCI_BlueBand, + gdal.GCI_NIRBand, + gdal.GCI_RedEdgeBand, + gdal.GCI_CoastalBand, + ] rgb_ds = gdal.Open("data/dimap2/vhr2020_ms_fs/MS-FS/IMG_RGB_R1C1.TIF") ned_ds = gdal.Open("data/dimap2/vhr2020_ms_fs/MS-FS/IMG_NED_R1C1.TIF") assert ds.ReadRaster() == rgb_ds.ReadRaster() + ned_ds.ReadRaster() diff --git a/autotest/gdrivers/dipex.py b/autotest/gdrivers/dipex.py index 91fafb02e3db..7ee22a86a99a 100755 --- a/autotest/gdrivers/dipex.py +++ b/autotest/gdrivers/dipex.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/doq1.py b/autotest/gdrivers/doq1.py index a62eb6ce923c..248e7210f9fb 100755 --- a/autotest/gdrivers/doq1.py +++ b/autotest/gdrivers/doq1.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/doq2.py b/autotest/gdrivers/doq2.py index 7f510ceed329..f838f6cfcaac 100755 --- a/autotest/gdrivers/doq2.py +++ b/autotest/gdrivers/doq2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/dted.py b/autotest/gdrivers/dted.py index e2d0c1a3d0c9..a18a034247f4 100755 --- a/autotest/gdrivers/dted.py +++ b/autotest/gdrivers/dted.py @@ -11,23 +11,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2007-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/ecrgtoc.py b/autotest/gdrivers/ecrgtoc.py index c023dc38f01b..8ada6bd9a73e 100755 --- a/autotest/gdrivers/ecrgtoc.py +++ b/autotest/gdrivers/ecrgtoc.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/ecw.py b/autotest/gdrivers/ecw.py index d0407441e7fd..2ef47be51da9 100755 --- a/autotest/gdrivers/ecw.py +++ b/autotest/gdrivers/ecw.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -111,6 +95,10 @@ def startup_and_cleanup(): else: gdaltest.ecw_drv.major_version = 3 gdaltest.ecw_drv.minor_version = 3 + gdaltest.ecw_drv.version = ( + gdaltest.ecw_drv.major_version, + gdaltest.ecw_drv.minor_version, + ) # we set ECW to not resolve projection and datum strings to get 3.x behavior. with gdal.config_option("ECW_DO_NOT_RESOLVE_DATUM_PROJECTION", "YES"): @@ -1038,6 +1026,10 @@ def test_ecw_31(): # It ignores the content of panBandMap. (#4234) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_ecw_32(): ds = gdal.Open("data/ecw/jrc.ecw") @@ -2477,3 +2469,16 @@ def test_ecw_online_7(): expected_band_count, ds.RasterCount, ) + + +############################################################################### +# Test reading a dataset whose tile dimensions are larger than dataset ones + + +def test_ecw_byte_tile_2048(): + + ds = gdal.Open("data/jpeg2000/byte_tile_2048.jp2") + (blockxsize, blockysize) = ds.GetRasterBand(1).GetBlockSize() + assert (blockxsize, blockysize) == ( + (20, 20) if gdaltest.ecw_drv.version >= (5, 1) else (256, 256) + ) diff --git a/autotest/gdrivers/eedai.py b/autotest/gdrivers/eedai.py index 39a15f90d5f8..6e94c5352403 100755 --- a/autotest/gdrivers/eedai.py +++ b/autotest/gdrivers/eedai.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -302,7 +286,8 @@ def test_eedai_3(): # Test OAuth2 with GOOGLE_APPLICATION_CREDENTIALS -def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(): +@pytest.mark.parametrize("use_vsi_path", [False, True]) +def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(use_vsi_path): gdal.FileFromMemBuffer( "/vsimem/my.json", @@ -313,7 +298,12 @@ def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(): ) gdal.SetConfigOption("EEDA_URL", "/vsimem/ee/") - gdal.SetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", "/vsimem/my.json") + if use_vsi_path: + gdal.SetPathSpecificOption( + "/vsigs/to_test_eeda", "GOOGLE_APPLICATION_CREDENTIALS", "/vsimem/my.json" + ) + else: + gdal.SetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", "/vsimem/my.json") gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) gdal.SetConfigOption("GO2A_AUD", "/vsimem/oauth2/v4/token") @@ -323,8 +313,11 @@ def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(): '{ "access_token": "my_token", "token_type": "Bearer", "expires_in": 3600 }', ) + open_options = [] + if use_vsi_path: + open_options.append("VSI_PATH_FOR_AUTH=/vsigs/to_test_eeda") try: - ds = gdal.Open("EEDAI:image") + ds = gdal.OpenEx("EEDAI:image", open_options=open_options) assert ds is not None except RuntimeError: pass @@ -335,6 +328,7 @@ def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(): gdal.SetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", None) gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) + gdal.ClearPathSpecificOptions("/vsigs/to_test_eeda") if "CPLRSASHA256Sign() not implemented" in gdal.GetLastErrorMsg(): pytest.skip("CPLRSASHA256Sign() not implemented") diff --git a/autotest/gdrivers/ehdr.py b/autotest/gdrivers/ehdr.py index 6fb4b75b747f..d5687c8f08c0 100755 --- a/autotest/gdrivers/ehdr.py +++ b/autotest/gdrivers/ehdr.py @@ -11,23 +11,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -153,6 +137,10 @@ def test_ehdr_7(): # Test signed 8bit integer support. (#2717) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_ehdr_8(): drv = gdal.GetDriverByName("EHDR") diff --git a/autotest/gdrivers/eir.py b/autotest/gdrivers/eir.py index 58c0db273e9f..e6bce73bcf58 100755 --- a/autotest/gdrivers/eir.py +++ b/autotest/gdrivers/eir.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/elas.py b/autotest/gdrivers/elas.py index c62e870d1cc7..7bba07b144fc 100755 --- a/autotest/gdrivers/elas.py +++ b/autotest/gdrivers/elas.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/envi.py b/autotest/gdrivers/envi.py index 9cc41b9f074e..d415c1e2cb57 100755 --- a/autotest/gdrivers/envi.py +++ b/autotest/gdrivers/envi.py @@ -13,23 +13,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2009-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -1056,3 +1040,120 @@ def test_envi_read_metadata_with_leading_space(): assert ds.GetRasterBand(1).GetMetadataItem("wavelength") == "3" ds = None gdal.GetDriverByName("ENVI").Delete("/vsimem/test.bin") + + +############################################################################### +# Test wavelength / fwhm + + +def test_envi_read_wavelength_fwhm_um(): + + gdal.FileFromMemBuffer( + "/vsimem/test.hdr", + """ENVI +samples = 1 +lines = 1 +bands = 3 +header offset = 0 +file type = ENVI Standard +data type = 1 +interleave = bip +sensor type = Unknown +byte order = 0 +wavelength units = um +wavelength = {3, 2, 1} +fwhm = {.3, .2, .1}""", + ) + gdal.FileFromMemBuffer("/vsimem/test.bin", "xyz") + + ds = gdal.Open("/vsimem/test.bin") + assert ( + ds.GetRasterBand(1).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "3.000" + ) + assert ds.GetRasterBand(1).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.300" + assert ( + ds.GetRasterBand(2).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "2.000" + ) + assert ds.GetRasterBand(2).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.200" + ds = None + gdal.GetDriverByName("ENVI").Delete("/vsimem/test.bin") + + +############################################################################### +# Test wavelength / fwhm + + +def test_envi_read_wavelength_fwhm_nm(): + + gdal.FileFromMemBuffer( + "/vsimem/test.hdr", + """ENVI +samples = 1 +lines = 1 +bands = 3 +header offset = 0 +file type = ENVI Standard +data type = 1 +interleave = bip +sensor type = Unknown +byte order = 0 +wavelength units = nm +wavelength = {3000, 2000, 1000} +fwhm = {300, 200, 100}""", + ) + gdal.FileFromMemBuffer("/vsimem/test.bin", "xyz") + + ds = gdal.Open("/vsimem/test.bin") + assert ( + ds.GetRasterBand(1).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "3.000" + ) + assert ds.GetRasterBand(1).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.300" + assert ( + ds.GetRasterBand(2).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "2.000" + ) + assert ds.GetRasterBand(2).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.200" + ds = None + gdal.GetDriverByName("ENVI").Delete("/vsimem/test.bin") + + +############################################################################### +# Test wavelength / fwhm + + +def test_envi_read_wavelength_fwhm_mm(): + + gdal.FileFromMemBuffer( + "/vsimem/test.hdr", + """ENVI +samples = 1 +lines = 1 +bands = 3 +header offset = 0 +file type = ENVI Standard +data type = 1 +interleave = bip +sensor type = Unknown +byte order = 0 +wavelength units = mm +wavelength = {0.003, 0.002, 0.001} +fwhm = {0.0003, 0.0002, 0.0001}""", + ) + gdal.FileFromMemBuffer("/vsimem/test.bin", "xyz") + + ds = gdal.Open("/vsimem/test.bin") + assert ( + ds.GetRasterBand(1).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "3.000" + ) + assert ds.GetRasterBand(1).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.300" + assert ( + ds.GetRasterBand(2).GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") + == "2.000" + ) + assert ds.GetRasterBand(2).GetMetadataItem("FWHM_UM", "IMAGERY") == "0.200" + ds = None + gdal.GetDriverByName("ENVI").Delete("/vsimem/test.bin") diff --git a/autotest/gdrivers/envisat.py b/autotest/gdrivers/envisat.py index 36d111f6117c..768cb241be2e 100755 --- a/autotest/gdrivers/envisat.py +++ b/autotest/gdrivers/envisat.py @@ -11,23 +11,7 @@ # Copyright (c) 2011, Antonio Valentino # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gzip @@ -76,7 +60,7 @@ def _get_mds_num(filename): # -class EnvisatTestBase(object): +class EnvisatTestBase: # Just a base class def download_file(self): diff --git a/autotest/gdrivers/ers.py b/autotest/gdrivers/ers.py index 701580704ac9..0bfd6abf93f8 100755 --- a/autotest/gdrivers/ers.py +++ b/autotest/gdrivers/ers.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -140,6 +124,10 @@ def test_ers_7(): # Test GCP support +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_ers_8(): src_ds = gdal.Open("../gcore/data/gcps.vrt") diff --git a/autotest/gdrivers/esric.py b/autotest/gdrivers/esric.py index e5c8ddf5066c..32f075e8f81a 100755 --- a/autotest/gdrivers/esric.py +++ b/autotest/gdrivers/esric.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2020, Esri # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/exr.py b/autotest/gdrivers/exr.py index de3641221b31..56a6c785eddd 100644 --- a/autotest/gdrivers/exr.py +++ b/autotest/gdrivers/exr.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/fast.py b/autotest/gdrivers/fast.py index 7cc2dbe50969..bcfbf9a1c705 100755 --- a/autotest/gdrivers/fast.py +++ b/autotest/gdrivers/fast.py @@ -10,23 +10,7 @@ # Copyright (c) 2007, Mateusz Loskot # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/fit.py b/autotest/gdrivers/fit.py index bf20aad0ae48..404c0f74c8fe 100755 --- a/autotest/gdrivers/fit.py +++ b/autotest/gdrivers/fit.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/fits.py b/autotest/gdrivers/fits.py index dae9ab9461bc..ca18ee7372c3 100755 --- a/autotest/gdrivers/fits.py +++ b/autotest/gdrivers/fits.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008,2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/gdalhttp.py b/autotest/gdrivers/gdalhttp.py index 4ab2831cce7a..40231a90e658 100755 --- a/autotest/gdrivers/gdalhttp.py +++ b/autotest/gdrivers/gdalhttp.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2009-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/genbin.py b/autotest/gdrivers/genbin.py index 795b87f65ab4..732ac3e8b2fa 100755 --- a/autotest/gdrivers/genbin.py +++ b/autotest/gdrivers/genbin.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/generate_fits.py b/autotest/gdrivers/generate_fits.py index b2e9a2305926..9001f7d00b93 100644 --- a/autotest/gdrivers/generate_fits.py +++ b/autotest/gdrivers/generate_fits.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/georaster.py b/autotest/gdrivers/georaster.py index 30a11919c7dd..db5956f5f007 100755 --- a/autotest/gdrivers/georaster.py +++ b/autotest/gdrivers/georaster.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, Ivan Lucena # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/gff.py b/autotest/gdrivers/gff.py index 7267f7771007..71b903c8882f 100755 --- a/autotest/gdrivers/gff.py +++ b/autotest/gdrivers/gff.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/gif.py b/autotest/gdrivers/gif.py index 3b321abd2594..32288405d39a 100755 --- a/autotest/gdrivers/gif.py +++ b/autotest/gdrivers/gif.py @@ -10,23 +10,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/gpkg.py b/autotest/gdrivers/gpkg.py index 304d0e0b9262..7896951a17ec 100755 --- a/autotest/gdrivers/gpkg.py +++ b/autotest/gdrivers/gpkg.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -850,6 +834,10 @@ def test_gpkg_10(): # Single band with 32 bit color table +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.parametrize("tile_drv_name", ["JPEG", "WEBP"]) def test_gpkg_11(tile_drv_name): diff --git a/autotest/gdrivers/grassasciigrid.py b/autotest/gdrivers/grassasciigrid.py index faf9fa90a170..320b45adc8a8 100755 --- a/autotest/gdrivers/grassasciigrid.py +++ b/autotest/gdrivers/grassasciigrid.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/grib.py b/autotest/gdrivers/grib.py index 66efaa6aef83..f8a0c12002fd 100755 --- a/autotest/gdrivers/grib.py +++ b/autotest/gdrivers/grib.py @@ -11,23 +11,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -1732,7 +1716,8 @@ def test_grib_grib2_write_data_encodings_warnings_and_errors(): tests += [["data/byte.tif", ["JPEG2000_DRIVER=DERIVED"]]] # Read-only driver tests += [["../gcore/data/cfloat32.tif", []]] # complex data type tests += [["data/aaigrid/float64.asc", []]] # no projection - tests += [["data/test_nosrs.vrt", []]] # no geotransform + if gdaltest.vrt_has_open_support(): + tests += [["data/test_nosrs.vrt", []]] # no geotransform tests += [["data/envi/rotation.img", []]] # geotransform with rotation terms gdal.GetDriverByName("GTiff").Create( "/vsimem/huge.tif", 65535, 65535, 1, options=["SPARSE_OK=YES"] diff --git a/autotest/gdrivers/gribmultidim.py b/autotest/gdrivers/gribmultidim.py index ae537b83a3e5..be55bec53338 100755 --- a/autotest/gdrivers/gribmultidim.py +++ b/autotest/gdrivers/gribmultidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gdrivers/gsc.py b/autotest/gdrivers/gsc.py index f72131390ef8..82e8b4a6a22f 100755 --- a/autotest/gdrivers/gsc.py +++ b/autotest/gdrivers/gsc.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/gsg.py b/autotest/gdrivers/gsg.py index 395fe918826a..4af7a31f4b55 100755 --- a/autotest/gdrivers/gsg.py +++ b/autotest/gdrivers/gsg.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, Andrey Kiselev # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/gta.py b/autotest/gdrivers/gta.py index 556dec404f59..cef89095a7c0 100755 --- a/autotest/gdrivers/gta.py +++ b/autotest/gdrivers/gta.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -98,6 +82,10 @@ def test_gta_2(): # Test writing and readings GCPs +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gta_3(): src_ds = gdal.Open("../gcore/data/gcps.vrt") diff --git a/autotest/gdrivers/gti.py b/autotest/gdrivers/gti.py index 2bab88273269..c9691ebd0574 100755 --- a/autotest/gdrivers/gti.py +++ b/autotest/gdrivers/gti.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -820,9 +804,9 @@ def test_gti_invalid_srs(tmp_vsimem): gdal.Open(index_filename) -def test_gti_valid_srs(tmp_vsimem): +def test_gti_valid_srs(tmp_path): - index_filename = str(tmp_vsimem / "index.gti.gpkg") + index_filename = str(tmp_path / "index.gti.gpkg") src_ds = gdal.Open(os.path.join(os.getcwd(), "data", "byte.tif")) index_ds, lyr = create_basic_tileindex(index_filename, src_ds) @@ -1019,6 +1003,10 @@ def test_gti_no_metadata_rgb(tmp_vsimem): check_basic(vrt_ds, src_ds) +@pytest.mark.skipif( + gdal.GetDriverByName("VRT").GetMetadataItem(gdal.DMD_OPENOPTIONLIST) is None, + reason="VRT driver open missing", +) def test_gti_rgb_left_right(tmp_vsimem): index_filename = str(tmp_vsimem / "index.gti.gpkg") @@ -1078,6 +1066,10 @@ def test_gti_rgb_left_right(tmp_vsimem): assert flags == gdal.GDAL_DATA_COVERAGE_STATUS_DATA and pct == 100.0 +@pytest.mark.skipif( + gdal.GetDriverByName("VRT").GetMetadataItem(gdal.DMD_OPENOPTIONLIST) is None, + reason="VRT driver open missing", +) def test_gti_overlapping_sources(tmp_vsimem): filename1 = str(tmp_vsimem / "one.tif") @@ -1345,6 +1337,10 @@ def test_gti_overlapping_sources(tmp_vsimem): assert vrt_ds.GetRasterBand(1).Checksum() == 2, sort_values +@pytest.mark.skipif( + gdal.GetDriverByName("VRT").GetMetadataItem(gdal.DMD_OPENOPTIONLIST) is None, + reason="VRT driver open missing", +) def test_gti_gap_between_sources(tmp_vsimem): filename1 = str(tmp_vsimem / "one.tif") @@ -1380,6 +1376,10 @@ def test_gti_gap_between_sources(tmp_vsimem): ) +@pytest.mark.skipif( + gdal.GetDriverByName("VRT").GetMetadataItem(gdal.DMD_OPENOPTIONLIST) is None, + reason="VRT driver open missing", +) def test_gti_no_source(tmp_vsimem): index_filename = str(tmp_vsimem / "index.gti.gpkg") @@ -2954,6 +2954,9 @@ def test_gti_read_multi_threaded_disabled_because_truncated_source(tmp_vsimem): @pytest.mark.require_curl() @pytest.mark.require_driver("Parquet") +@pytest.mark.xfail( + reason="https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_nw_14_1_20100425.tif now leads to HTTP/1.1 409 Public access is not permitted on this storage account." +) def test_gti_stac_geoparquet(): url = ( diff --git a/autotest/gdrivers/gtx.py b/autotest/gdrivers/gtx.py index 6fed29fb51db..b217db1674d4 100755 --- a/autotest/gdrivers/gtx.py +++ b/autotest/gdrivers/gtx.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/gxf.py b/autotest/gdrivers/gxf.py index 1eec4661677a..d1657b6d0d99 100755 --- a/autotest/gdrivers/gxf.py +++ b/autotest/gdrivers/gxf.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/hdf5.py b/autotest/gdrivers/hdf5.py index eeb37a422247..48b0eede7fac 100755 --- a/autotest/gdrivers/hdf5.py +++ b/autotest/gdrivers/hdf5.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -52,7 +36,9 @@ def check_no_file_leaks(): yield diff = len(gdaltest.get_opened_files()) - num_files - assert diff == 0, "Leak of file handles: %d leaked" % diff + # For some weird reason, we sometimes get less files opened than at the + # start. Cf https://github.com/OSGeo/gdal/actions/runs/11349015748/job/31564138716?pr=10896 + assert diff <= 0, "Leak of file handles: %d leaked" % diff ############################################################################### diff --git a/autotest/gdrivers/hdf5multidim.py b/autotest/gdrivers/hdf5multidim.py index 31260e9ab766..2a2280a615b6 100755 --- a/autotest/gdrivers/hdf5multidim.py +++ b/autotest/gdrivers/hdf5multidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gdrivers/heif.py b/autotest/gdrivers/heif.py index 92fd99640806..9bcefc45779a 100644 --- a/autotest/gdrivers/heif.py +++ b/autotest/gdrivers/heif.py @@ -10,25 +10,10 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import array import os import shutil @@ -48,8 +33,35 @@ def get_version(): ] +def _has_tiling_support(): + drv = gdal.GetDriverByName("HEIF") + return drv and drv.GetMetadataItem("SUPPORTS_TILES", "HEIF") + + +def _has_hevc_decoding_support(): + drv = gdal.GetDriverByName("HEIF") + return drv and drv.GetMetadataItem("SUPPORTS_HEVC", "HEIF") + + +def _has_uncompressed_decoding_support(): + drv = gdal.GetDriverByName("HEIF") + return drv and drv.GetMetadataItem("SUPPORTS_UNCOMPRESSED", "HEIF") + + +def _has_read_write_support_for(format): + drv = gdal.GetDriverByName("HEIF") + return ( + drv + and drv.GetMetadataItem("SUPPORTS_" + format, "HEIF") + and drv.GetMetadataItem("SUPPORTS_" + format + "_WRITE", "HEIF") + ) + + @pytest.mark.parametrize("endianness", ["big_endian", "little_endian"]) def test_heif_exif_endian(endianness): + if not _has_hevc_decoding_support(): + pytest.skip() + filename = "data/heif/byte_exif_%s.heic" % endianness gdal.ErrorReset() ds = gdal.Open(filename) @@ -79,6 +91,9 @@ def test_heif_exif_endian(endianness): def test_heif_thumbnail(): + if not _has_hevc_decoding_support(): + pytest.skip() + ds = gdal.Open("data/heif/byte_thumbnail.heic") assert ds assert ds.RasterXSize == 128 @@ -97,6 +112,8 @@ def test_heif_thumbnail(): def test_heif_rgb_16bit(): if get_version() < [1, 4, 0]: pytest.skip() + if not _has_hevc_decoding_support(): + pytest.skip() ds = gdal.Open("data/heif/small_world_16.heic") assert ds @@ -109,6 +126,8 @@ def test_heif_rgb_16bit(): def test_heif_rgba(): + if not _has_hevc_decoding_support(): + pytest.skip() ds = gdal.Open("data/heif/stefan_full_rgba.heic") assert ds @@ -126,6 +145,8 @@ def test_heif_rgba(): def test_heif_rgba_16bit(): if get_version() < [1, 4, 0]: pytest.skip() + if not _has_hevc_decoding_support(): + pytest.skip() ds = gdal.Open("data/heif/stefan_full_rgba_16.heic") assert ds @@ -133,7 +154,249 @@ def test_heif_rgba_16bit(): assert ds.GetRasterBand(1).DataType == gdal.GDT_UInt16 +def test_heif_tiled(): + if not _has_tiling_support(): + pytest.skip() + if not _has_uncompressed_decoding_support(): + pytest.skip() + + ds = gdal.Open("data/heif/uncompressed_comp_RGB_tiled.heif") + assert ds + assert ds.RasterXSize == 30 + assert ds.RasterYSize == 20 + assert ds.RasterCount == 3 + assert ds.GetRasterBand(1).DataType == gdal.GDT_Byte + assert ds.GetRasterBand(1).GetBlockSize() == [15, 5] + assert ds.GetRasterBand(2).GetBlockSize() == [15, 5] + assert ds.GetRasterBand(3).GetBlockSize() == [15, 5] + pytest.importorskip("osgeo.gdal_array") + assert ( + ds.GetRasterBand(1).ReadAsArray(0, 0, 30, 1) + == [ + [ + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 128, + 128, + ] + ] + ).all() + assert ( + ds.GetRasterBand(1).ReadAsArray(0, 19, 30, 1) + == [ + [ + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 128, + 128, + 128, + 128, + 255, + 255, + 255, + 255, + 238, + 238, + 238, + 238, + 255, + 255, + 255, + 255, + 0, + 0, + ] + ] + ).all() + assert ( + ds.GetRasterBand(2).ReadAsArray(0, 0, 30, 1) + == [ + [ + 0, + 0, + 0, + 0, + 128, + 128, + 128, + 128, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 128, + 128, + ] + ] + ).all() + assert ( + ds.GetRasterBand(2).ReadAsArray(0, 19, 30, 1) + == [ + [ + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 128, + 128, + 128, + 128, + 165, + 165, + 165, + 165, + 130, + 130, + 130, + 130, + 0, + 0, + 0, + 0, + 128, + 128, + ] + ] + ).all() + assert ( + ds.GetRasterBand(3).ReadAsArray(0, 0, 30, 1) + == [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 128, + 128, + ] + ] + ).all() + assert ( + ds.GetRasterBand(3).ReadAsArray(0, 19, 30, 1) + == [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, + 128, + 128, + 128, + 128, + 0, + 0, + 0, + 0, + 238, + 238, + 238, + 238, + 0, + 0, + 0, + 0, + 0, + 0, + ] + ] + ).all() + + def test_heif_subdatasets(tmp_path): + if not _has_hevc_decoding_support(): + pytest.skip() filename = str(tmp_path / "out.heic") shutil.copy("data/heif/subdatasets.heic", filename) @@ -230,3 +493,127 @@ def test_identify_various(major_brand, compatible_brands, expect_success): assert drv is None gdal.Unlink("/vsimem/heif_header.bin") + + +def make_data(): + ds = gdal.GetDriverByName("MEM").Create("", 300, 200, 3, gdal.GDT_Byte) + + ds.GetRasterBand(1).SetRasterColorInterpretation(gdal.GCI_RedBand) + ds.GetRasterBand(2).SetRasterColorInterpretation(gdal.GCI_GreenBand) + ds.GetRasterBand(3).SetRasterColorInterpretation(gdal.GCI_BlueBand) + + red_green_blue = ( + ([0xFF] * 100 + [0x00] * 200) + + ([0x00] * 100 + [0xFF] * 100 + [0x00] * 100) + + ([0x00] * 200 + [0xFF] * 100) + ) + rgb_bytes = array.array("B", red_green_blue).tobytes() + for line in range(100): + ds.WriteRaster( + 0, line, 300, 1, rgb_bytes, buf_type=gdal.GDT_Byte, band_list=[1, 2, 3] + ) + black_white = ([0xFF] * 150 + [0x00] * 150) * 3 + black_white_bytes = array.array("B", black_white).tobytes() + for line in range(100): + ds.WriteRaster( + 0, + 100 + line, + 300, + 1, + black_white_bytes, + buf_type=gdal.GDT_Byte, + band_list=[1, 2, 3], + ) + + assert ds.FlushCache() == gdal.CE_None + return ds + + +def make_data_with_alpha(): + ds = gdal.GetDriverByName("MEM").Create("", 300, 200, 4, gdal.GDT_Byte) + + ds.GetRasterBand(1).SetRasterColorInterpretation(gdal.GCI_RedBand) + ds.GetRasterBand(2).SetRasterColorInterpretation(gdal.GCI_GreenBand) + ds.GetRasterBand(3).SetRasterColorInterpretation(gdal.GCI_BlueBand) + ds.GetRasterBand(4).SetRasterColorInterpretation(gdal.GCI_AlphaBand) + + red_green_blue_alpha = ( + ([0xFF] * 100 + [0x00] * 200) + + ([0x00] * 100 + [0xFF] * 100 + [0x00] * 100) + + ([0x00] * 200 + [0xFF] * 100) + + ([0x7F] * 150 + [0xFF] * 150) + ) + rgba_bytes = array.array("B", red_green_blue_alpha).tobytes() + for line in range(100): + ds.WriteRaster( + 0, line, 300, 1, rgba_bytes, buf_type=gdal.GDT_Byte, band_list=[1, 2, 3, 4] + ) + black_white = ([0xFF] * 150 + [0x00] * 150) * 4 + black_white_bytes = array.array("B", black_white).tobytes() + for line in range(100): + ds.WriteRaster( + 0, + 100 + line, + 300, + 1, + black_white_bytes, + buf_type=gdal.GDT_Byte, + band_list=[1, 2, 3, 4], + ) + + assert ds.FlushCache() == gdal.CE_None + return ds + + +heif_codecs = ["AV1", "HEVC", "JPEG", "JPEG2000", "UNCOMPRESSED"] + + +@pytest.mark.parametrize("codec", heif_codecs) +def test_heif_create_copy(tmp_path, codec): + if not _has_read_write_support_for(codec): + pytest.skip() + tempfile = str(tmp_path / ("test_heif_create_copy_" + codec + ".hif")) + input_ds = make_data() + + drv = gdal.GetDriverByName("HEIF") + result_ds = drv.CreateCopy(tempfile, input_ds, options=["CODEC=" + codec]) + + result_ds = None + + result_ds = gdal.Open(tempfile) + + assert result_ds + + +@pytest.mark.parametrize("codec", heif_codecs) +def test_heif_create_copy_with_alpha(tmp_path, codec): + if not _has_read_write_support_for(codec): + pytest.skip() + tempfile = str(tmp_path / ("test_heif_create_copy_" + codec + "_alpha.hif")) + input_ds = make_data_with_alpha() + + drv = gdal.GetDriverByName("HEIF") + result_ds = drv.CreateCopy(tempfile, input_ds, options=["CODEC=" + codec]) + + result_ds = None + + result_ds = gdal.Open(tempfile) + + assert result_ds + + +def test_heif_create_copy_defaults(tmp_path): + if not _has_read_write_support_for("HEVC"): + pytest.skip() + tempfile = str(tmp_path / "test_heif_create_copy.hif") + input_ds = make_data() + + drv = gdal.GetDriverByName("HEIF") + + result_ds = drv.CreateCopy(tempfile, input_ds, options=[]) + + result_ds = None + + result_ds = gdal.Open(tempfile) + + assert result_ds diff --git a/autotest/gdrivers/hf2.py b/autotest/gdrivers/hf2.py index 926d110aad3b..6499a65c83db 100755 --- a/autotest/gdrivers/hf2.py +++ b/autotest/gdrivers/hf2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/hfa.py b/autotest/gdrivers/hfa.py index e68e2236bbe8..3b72e082dcc2 100755 --- a/autotest/gdrivers/hfa.py +++ b/autotest/gdrivers/hfa.py @@ -10,23 +10,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -38,6 +22,8 @@ from osgeo import gdal +pytestmark = pytest.mark.require_driver("HFA") + ############################################################################### # Verify we can read the special histogram metadata from a provided image. @@ -666,6 +652,10 @@ def test_hfa_vsimem(): # the .img file. (#2422) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_hfa_proName(): drv = gdal.GetDriverByName("HFA") diff --git a/autotest/gdrivers/idrisi.py b/autotest/gdrivers/idrisi.py index e12243136cec..28be6e5fd407 100755 --- a/autotest/gdrivers/idrisi.py +++ b/autotest/gdrivers/idrisi.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2006, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil diff --git a/autotest/gdrivers/ilwis.py b/autotest/gdrivers/ilwis.py index ee3ab8995ced..fccb9d336167 100755 --- a/autotest/gdrivers/ilwis.py +++ b/autotest/gdrivers/ilwis.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2005, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/iris.py b/autotest/gdrivers/iris.py index 211a939e6ebb..09da26c8f18b 100755 --- a/autotest/gdrivers/iris.py +++ b/autotest/gdrivers/iris.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/isce.py b/autotest/gdrivers/isce.py index 7f7135fbf65c..45f5255edede 100755 --- a/autotest/gdrivers/isce.py +++ b/autotest/gdrivers/isce.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, Matthieu Volat # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/isg.py b/autotest/gdrivers/isg.py index 89aae7c3c305..0b76a16303e8 100755 --- a/autotest/gdrivers/isg.py +++ b/autotest/gdrivers/isg.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/isis.py b/autotest/gdrivers/isis.py index 9f04f9e9b528..798b5a0f3392 100755 --- a/autotest/gdrivers/isis.py +++ b/autotest/gdrivers/isis.py @@ -10,23 +10,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2017, Hobu Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/gdrivers/isis2.py b/autotest/gdrivers/isis2.py index a2601e89087a..8adb883f2f46 100755 --- a/autotest/gdrivers/isis2.py +++ b/autotest/gdrivers/isis2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/jdem.py b/autotest/gdrivers/jdem.py index ab7a33149dbf..4cd6f4702c09 100755 --- a/autotest/gdrivers/jdem.py +++ b/autotest/gdrivers/jdem.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/jp2kak.py b/autotest/gdrivers/jp2kak.py index 63cc74f1fd39..21549b715484 100755 --- a/autotest/gdrivers/jp2kak.py +++ b/autotest/gdrivers/jp2kak.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/jp2lura.py b/autotest/gdrivers/jp2lura.py deleted file mode 100755 index df6fb0543ea0..000000000000 --- a/autotest/gdrivers/jp2lura.py +++ /dev/null @@ -1,2321 +0,0 @@ -#!/usr/bin/env pytest -# -*- coding: utf-8 -*- -############################################################################### -# $Id$ -# -# Project: GDAL/OGR Test Suite -# Purpose: Test read/write functionality for JP2Lura driver. -# Author: Even Rouault -# -############################################################################### -# Copyright (c) 2016, 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 os -import shutil -import struct -import sys - -import gdaltest -import pytest -from test_py_scripts import samples_path - -from osgeo import gdal, ogr, osr - - -############################################################################### -@pytest.fixture(autouse=True, scope="module") -def module_disable_exceptions(): - with gdaltest.disable_exceptions(): - yield - - -def jp2lura_available(): - - if ( - gdal.GetConfigOption("LURA_LICENSE_NUM_1") is None - or gdal.GetConfigOption("LURA_LICENSE_NUM_2") is None - ): - return False - - gdaltest.deregister_all_jpeg2000_drivers_but("JP2Lura") - ds = gdal.Open(os.path.join(os.path.dirname(__file__), "data/jpeg2000/byte.jp2")) - gdaltest.reregister_all_jpeg2000_drivers() - return ds is not None - - -pytestmark = [ - pytest.mark.require_driver("JP2Lura"), - pytest.mark.skipif( - not jp2lura_available(), - reason="JP2Lura driver not available or missing license", - ), -] - -############################################################################### -@pytest.fixture(autouse=True, scope="module") -def startup_and_cleanup(): - - gdaltest.jp2lura_drv = gdal.GetDriverByName("JP2Lura") - assert gdaltest.jp2lura_drv is not None - - gdaltest.deregister_all_jpeg2000_drivers_but("JP2Lura") - - yield - - gdaltest.reregister_all_jpeg2000_drivers() - - -############################################################################### -# - - -def test_jp2lura_missing_license_num(): - - with gdal.config_options( - {"LURA_LICENSE_NUM_1": "", "LURA_LICENSE_NUM_2": ""} - ), gdaltest.error_handler(): - ds = gdal.Open("data/jpeg2000/byte.jp2") - - assert ds is None - - -############################################################################### -# - - -def test_jp2lura_invalid_license_num(): - - with gdal.config_options( - {"LURA_LICENSE_NUM_1": "1", "LURA_LICENSE_NUM_2": "2"} - ), gdaltest.error_handler(): - ds = gdal.Open("data/jpeg2000/byte.jp2") - - assert ds is None - - -############################################################################### - - -def validate( - filename, - expected_gmljp2=True, - return_error_count=False, - oidoc=None, - inspire_tg=True, -): - - path = samples_path - if path not in sys.path: - sys.path.append(path) - validate_jp2 = pytest.importorskip("validate_jp2") - - try: - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET") - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET/xlink.xsd") - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET/xml.xsd") - ogc_schemas_location = "tmp/cache/SCHEMAS_OPENGIS_NET" - except OSError: - ogc_schemas_location = "disabled" - - if ogc_schemas_location != "disabled": - try: - import xmlvalidate - - xmlvalidate.validate # to make pyflakes happy - except (ImportError, AttributeError): - ogc_schemas_location = "disabled" - - res = validate_jp2.validate( - filename, oidoc, inspire_tg, expected_gmljp2, ogc_schemas_location - ) - if return_error_count: - return (res.error_count, res.warning_count) - if res.error_count == 0 and res.warning_count == 0: - return - pytest.fail() - - -############################################################################### -# Open byte.jp2 - - -def test_jp2lura_2(): - - srs = """PROJCS["NAD27 / UTM zone 11N", - GEOGCS["NAD27", - DATUM["North_American_Datum_1927", - SPHEROID["Clarke 1866",6378206.4,294.9786982138982, - AUTHORITY["EPSG","7008"]], - AUTHORITY["EPSG","6267"]], - PRIMEM["Greenwich",0], - UNIT["degree",0.0174532925199433], - AUTHORITY["EPSG","4267"]], - PROJECTION["Transverse_Mercator"], - PARAMETER["latitude_of_origin",0], - PARAMETER["central_meridian",-117], - PARAMETER["scale_factor",0.9996], - PARAMETER["false_easting",500000], - PARAMETER["false_northing",0], - UNIT["metre",1, - AUTHORITY["EPSG","9001"]], - AUTHORITY["EPSG","26711"]] -""" - gt = (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0) - - tst = gdaltest.GDALTest("JP2Lura", "jpeg2000/byte.jp2", 1, 50054) - tst.testOpen(check_prj=srs, check_gt=gt) - - -############################################################################### -# Open int16.jp2 - - -def test_jp2lura_3(): - - ds = gdal.Open("data/jpeg2000/int16.jp2") - ds_ref = gdal.Open("data/int16.tif") - - maxdiff = gdaltest.compare_ds(ds, ds_ref) - print(ds.GetRasterBand(1).Checksum()) - print(ds_ref.GetRasterBand(1).Checksum()) - - ds = None - ds_ref = None - - # Quite a bit of difference... - assert maxdiff <= 6, "Image too different from reference" - - ds = ogr.Open("data/jpeg2000/int16.jp2") - assert ds is None - - -############################################################################### -# Test copying byte.jp2 - - -def test_jp2lura_4(out_filename="tmp/jp2lura_4.jp2"): - - src_ds = gdal.Open("data/jpeg2000/byte.jp2") - src_wkt = src_ds.GetProjectionRef() - src_gt = src_ds.GetGeoTransform() - - vrt_ds = gdal.GetDriverByName("VRT").CreateCopy("/vsimem/jp2lura_4.vrt", src_ds) - vrt_ds.SetMetadataItem("TIFFTAG_XRESOLUTION", "300") - vrt_ds.SetMetadataItem("TIFFTAG_YRESOLUTION", "200") - vrt_ds.SetMetadataItem("TIFFTAG_RESOLUTIONUNIT", "3 (pixels/cm)") - - gdal.Unlink(out_filename) - - out_ds = gdal.GetDriverByName("JP2Lura").CreateCopy( - out_filename, vrt_ds, options=["REVERSIBLE=YES"] - ) - del out_ds - - vrt_ds = None - gdal.Unlink("/vsimem/jp2lura_4.vrt") - - assert gdal.VSIStatL(out_filename + ".aux.xml") is None - - assert validate(out_filename, inspire_tg=False) != "fail" - - ds = gdal.Open(out_filename) - cs = ds.GetRasterBand(1).Checksum() - got_wkt = ds.GetProjectionRef() - got_gt = ds.GetGeoTransform() - xres = ds.GetMetadataItem("TIFFTAG_XRESOLUTION") - yres = ds.GetMetadataItem("TIFFTAG_YRESOLUTION") - resunit = ds.GetMetadataItem("TIFFTAG_RESOLUTIONUNIT") - ds = None - - gdal.Unlink(out_filename) - - assert ( - xres == "300" and yres == "200" and resunit == "3 (pixels/cm)" - ), "bad resolution" - - sr1 = osr.SpatialReference() - sr1.SetFromUserInput(got_wkt) - sr2 = osr.SpatialReference() - sr2.SetFromUserInput(src_wkt) - - if sr1.IsSame(sr2) == 0: - print(got_wkt) - print(src_wkt) - pytest.fail("bad spatial reference") - - for i in range(6): - assert got_gt[i] == pytest.approx(src_gt[i], abs=1e-8), "bad geotransform" - - assert cs == 50054, "bad checksum" - - -def test_jp2lura_4_vsimem(): - return test_jp2lura_4("/vsimem/jp2lura_4.jp2") - - -############################################################################### -# Test copying int16.jp2 - - -def test_jp2lura_5(): - - tst = gdaltest.GDALTest( - "JP2Lura", - "jpeg2000/int16.jp2", - 1, - None, - options=["REVERSIBLE=YES", "CODEC=J2K"], - ) - tst.testCreateCopy() - - -############################################################################### -# Test reading ll.jp2 - - -def test_jp2lura_6(): - - tst = gdaltest.GDALTest("JP2Lura", "jpeg2000/ll.jp2", 1, None) - - tst.testOpen() - - ds = gdal.Open("data/jpeg2000/ll.jp2") - ds.GetRasterBand(1).Checksum() - ds = None - - -############################################################################### -# Open byte.jp2.gz (test use of the VSIL API) - - -def test_jp2lura_7(): - - tst = gdaltest.GDALTest( - "JP2Lura", "/vsigzip/data/jpeg2000/byte.jp2.gz", 1, 50054, filename_absolute=1 - ) - tst.testOpen() - gdal.Unlink("data/jpeg2000/byte.jp2.gz.properties") - - -############################################################################### -# Test a JP2Lura with the 3 bands having 13bit depth and the 4th one 1 bit - - -def test_jp2lura_8(): - - ds = gdal.Open("data/jpeg2000/3_13bit_and_1bit.jp2") - - expected_checksums = [64570, 57277, 56048] # 61292] - - for i, csum in enumerate(expected_checksums): - assert ( - ds.GetRasterBand(i + 1).Checksum() == csum - ), "unexpected checksum (%d) for band %d" % (csum, i + 1) - - assert ds.GetRasterBand(1).DataType == gdal.GDT_UInt16, "unexpected data type" - - -############################################################################### -# Check that we can use .j2w world files (#4651) - - -def test_jp2lura_9(): - - ds = gdal.Open("data/jpeg2000/byte_without_geotransform.jp2") - - geotransform = ds.GetGeoTransform() - assert ( - geotransform[0] == pytest.approx(440720, abs=0.1) - and geotransform[1] == pytest.approx(60, abs=0.001) - and geotransform[2] == pytest.approx(0, abs=0.001) - and geotransform[3] == pytest.approx(3751320, abs=0.1) - and geotransform[4] == pytest.approx(0, abs=0.001) - and geotransform[5] == pytest.approx(-60, abs=0.001) - ), "geotransform differs from expected" - - ds = None - - -############################################################################### -# Test YCBCR420 creation option - - -def DISABLED_jp2lura_10(): - - src_ds = gdal.Open("data/rgbsmall.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_10.jp2", src_ds, options=["YCBCR420=YES", "RESOLUTIONS=3"] - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - assert out_ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_RedBand - assert out_ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert out_ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - del out_ds - src_ds = None - gdal.Unlink("/vsimem/jp2lura_10.jp2") - - # Quite a bit of difference... - assert maxdiff <= 12, "Image too different from reference" - - -############################################################################### -# Test auto-promotion of 1bit alpha band to 8bit - - -def DISABLED_jp2lura_11(): - - ds = gdal.Open("data/jpeg2000/stefan_full_rgba_alpha_1bit.jp2") - fourth_band = ds.GetRasterBand(4) - assert fourth_band.GetMetadataItem("NBITS", "IMAGE_STRUCTURE") is None - got_cs = fourth_band.Checksum() - assert got_cs == 8527 - jp2_bands_data = ds.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize) - jp2_fourth_band_data = fourth_band.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize) - fourth_band.ReadRaster( - 0, - 0, - ds.RasterXSize, - ds.RasterYSize, - int(ds.RasterXSize / 16), - int(ds.RasterYSize / 16), - ) - - tmp_ds = gdal.GetDriverByName("GTiff").CreateCopy("/vsimem/jp2lura_11.tif", ds) - fourth_band = tmp_ds.GetRasterBand(4) - got_cs = fourth_band.Checksum() - gtiff_bands_data = tmp_ds.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize) - gtiff_fourth_band_data = fourth_band.ReadRaster( - 0, 0, ds.RasterXSize, ds.RasterYSize - ) - # gtiff_fourth_band_subsampled_data = fourth_band.ReadRaster(0,0,ds.RasterXSize,ds.RasterYSize,ds.RasterXSize/16,ds.RasterYSize/16) - tmp_ds = None - gdal.GetDriverByName("GTiff").Delete("/vsimem/jp2lura_11.tif") - assert got_cs == 8527 - - assert jp2_bands_data == gtiff_bands_data - - assert jp2_fourth_band_data == gtiff_fourth_band_data - - ds = gdal.OpenEx( - "data/jpeg2000/stefan_full_rgba_alpha_1bit.jp2", - open_options=["1BIT_ALPHA_PROMOTION=NO"], - ) - fourth_band = ds.GetRasterBand(4) - assert fourth_band.GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "1" - - -############################################################################### -# Check that PAM overrides internal georeferencing (#5279) - - -def test_jp2lura_12(): - - # Override projection - shutil.copy("data/jpeg2000/byte.jp2", "tmp/jp2lura_12.jp2") - - ds = gdal.Open("tmp/jp2lura_12.jp2") - sr = osr.SpatialReference() - sr.ImportFromEPSG(32631) - ds.SetProjection(sr.ExportToWkt()) - ds = None - - ds = gdal.Open("tmp/jp2lura_12.jp2") - wkt = ds.GetProjectionRef() - ds = None - - gdaltest.jp2lura_drv.Delete("tmp/jp2lura_12.jp2") - - assert "32631" in wkt - - # Override geotransform - shutil.copy("data/jpeg2000/byte.jp2", "tmp/jp2lura_12.jp2") - - ds = gdal.Open("tmp/jp2lura_12.jp2") - ds.SetGeoTransform([1000, 1, 0, 2000, 0, -1]) - ds = None - - ds = gdal.Open("tmp/jp2lura_12.jp2") - gt = ds.GetGeoTransform() - ds = None - - gdaltest.jp2lura_drv.Delete("tmp/jp2lura_12.jp2") - - assert gt == (1000, 1, 0, 2000, 0, -1) - - -############################################################################### -# Check that PAM overrides internal GCPs (#5279) - - -def test_jp2lura_13(): - - # Create a dataset with GCPs - src_ds = gdal.Open("data/rgb_gcp.vrt") - ds = gdaltest.jp2lura_drv.CreateCopy("tmp/jp2lura_13.jp2", src_ds) - ds = None - src_ds = None - - assert gdal.VSIStatL("tmp/jp2lura_13.jp2.aux.xml") is None - - ds = gdal.Open("tmp/jp2lura_13.jp2") - count = ds.GetGCPCount() - gcps = ds.GetGCPs() - wkt = ds.GetGCPProjection() - assert count == 4 - assert len(gcps) == 4 - assert "4326" in wkt - ds = None - - # Override GCP - ds = gdal.Open("tmp/jp2lura_13.jp2") - sr = osr.SpatialReference() - sr.ImportFromEPSG(32631) - gcps = [gdal.GCP(0, 1, 2, 3, 4)] - ds.SetGCPs(gcps, sr.ExportToWkt()) - ds = None - - ds = gdal.Open("tmp/jp2lura_13.jp2") - count = ds.GetGCPCount() - gcps = ds.GetGCPs() - wkt = ds.GetGCPProjection() - ds = None - - gdaltest.jp2lura_drv.Delete("tmp/jp2lura_13.jp2") - - assert count == 1 - assert len(gcps) == 1 - assert "32631" in wkt - - -############################################################################### -# Check that we get GCPs even there's no projection info - - -def test_jp2lura_14(): - - ds = gdal.Open("data/jpeg2000/byte_2gcps.jp2") - assert ds.GetGCPCount() == 2 - - -############################################################################### -# Test reading PixelIsPoint file (#5437) - - -def test_jp2lura_16(): - - ds = gdal.Open("data/jpeg2000/byte_point.jp2") - gt = ds.GetGeoTransform() - assert ( - ds.GetMetadataItem("AREA_OR_POINT") == "Point" - ), "did not get AREA_OR_POINT = Point" - ds = None - - gt_expected = (440690.0, 60.0, 0.0, 3751350.0, 0.0, -60.0) - - assert gt == gt_expected, "did not get expected geotransform" - - with gdal.config_option("GTIFF_POINT_GEO_IGNORE", "TRUE"): - - ds = gdal.Open("data/jpeg2000/byte_point.jp2") - gt = ds.GetGeoTransform() - ds = None - - gt_expected = (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0) - - assert ( - gt == gt_expected - ), "did not get expected geotransform with GTIFF_POINT_GEO_IGNORE TRUE" - - -############################################################################### -# Test writing PixelIsPoint file (#5437) - - -def test_jp2lura_17(): - - src_ds = gdal.Open("data/jpeg2000/byte_point.jp2") - ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_17.jp2", src_ds) - ds = None - src_ds = None - - assert gdal.VSIStatL("/vsimem/jp2lura_17.jp2.aux.xml") is None - - ds = gdal.Open("/vsimem/jp2lura_17.jp2") - gt = ds.GetGeoTransform() - assert ( - ds.GetMetadataItem("AREA_OR_POINT") == "Point" - ), "did not get AREA_OR_POINT = Point" - ds = None - - gt_expected = (440690.0, 60.0, 0.0, 3751350.0, 0.0, -60.0) - - assert gt == gt_expected, "did not get expected geotransform" - - gdal.Unlink("/vsimem/jp2lura_17.jp2") - - -############################################################################### -# Test when using the decode_area API when one dimension of the dataset is not a -# multiple of 1024 (#5480) - - -def test_jp2lura_18(): - - src_ds = gdal.GetDriverByName("Mem").Create("", 2000, 2000) - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_18.jp2", src_ds, options=["TILEXSIZE=2000", "TILEYSIZE=2000"] - ) - ds = None - src_ds = None - - ds = gdal.Open("/vsimem/jp2lura_18.jp2") - ds.GetRasterBand(1).Checksum() - assert gdal.GetLastErrorMsg() == "" - ds = None - - gdal.Unlink("/vsimem/jp2lura_18.jp2") - - -############################################################################### -# Test reading file where GMLJP2 has nul character instead of \n (#5760) - - -def test_jp2lura_19(): - - ds = gdal.Open("data/jpeg2000/byte_gmljp2_with_nul_car.jp2") - assert ds.GetProjectionRef() != "" - ds = None - - -############################################################################### -# Validate GMLJP2 content against schema - - -def test_jp2lura_20(): - - xmlvalidate = pytest.importorskip("xmlvalidate") - - try: - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET.zip") - except OSError: - try: - os.stat("../ogr/tmp/cache/SCHEMAS_OPENGIS_NET.zip") - shutil.copy("../ogr/tmp/cache/SCHEMAS_OPENGIS_NET.zip", "tmp/cache") - except OSError: - url = "http://schemas.opengis.net/SCHEMAS_OPENGIS_NET.zip" - gdaltest.download_or_skip( - url, - "SCHEMAS_OPENGIS_NET.zip", - force_download=True, - max_download_duration=20, - ) - - try: - os.mkdir("tmp/cache/SCHEMAS_OPENGIS_NET") - except OSError: - pass - - try: - os.stat( - "tmp/cache/SCHEMAS_OPENGIS_NET/gml/3.1.1/profiles/gmlJP2Profile/1.0.0/gmlJP2Profile.xsd" - ) - except OSError: - gdaltest.unzip( - "tmp/cache/SCHEMAS_OPENGIS_NET", "tmp/cache/SCHEMAS_OPENGIS_NET.zip" - ) - - try: - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET/xlink.xsd") - except OSError: - xlink_xsd_url = "http://www.w3.org/1999/xlink.xsd" - if not gdaltest.download_file( - xlink_xsd_url, - "SCHEMAS_OPENGIS_NET/xlink.xsd", - force_download=True, - max_download_duration=10, - ): - xlink_xsd_url = "http://even.rouault.free.fr/xlink.xsd" - gdaltest.download_or_skip( - xlink_xsd_url, - "SCHEMAS_OPENGIS_NET/xlink.xsd", - force_download=True, - max_download_duration=10, - ) - - try: - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET/xml.xsd") - except OSError: - xlink_xsd_url = "http://www.w3.org/1999/xml.xsd" - if not gdaltest.download_file( - xlink_xsd_url, - "SCHEMAS_OPENGIS_NET/xml.xsd", - force_download=True, - max_download_duration=10, - ): - xlink_xsd_url = "http://even.rouault.free.fr/xml.xsd" - gdaltest.download_or_skip( - xlink_xsd_url, - "SCHEMAS_OPENGIS_NET/xml.xsd", - force_download=True, - max_download_duration=10, - ) - - xmlvalidate.transform_abs_links_to_ref_links("tmp/cache/SCHEMAS_OPENGIS_NET") - - src_ds = gdal.Open("data/byte.tif") - ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_20.jp2", src_ds) - gmljp2 = ds.GetMetadata_List("xml:gml.root-instance")[0] - ds = None - gdal.Unlink("/vsimem/jp2lura_20.jp2") - - assert xmlvalidate.validate( - gmljp2, ogc_schemas_location="tmp/cache/SCHEMAS_OPENGIS_NET" - ) - - -############################################################################### -# Test RGBA support - - -def test_jp2lura_22(): - - # RGBA - src_ds = gdal.Open("../gcore/data/stefan_full_rgba.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", src_ds, options=["REVERSIBLE=YES"] - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_22.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_RedBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(4).GetColorInterpretation() == gdal.GCI_AlphaBand - ds = None - - assert ( - validate("/vsimem/jp2lura_22.jp2", expected_gmljp2=False, inspire_tg=False) - != "fail" - ) - - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - if False: # pylint: disable=using-constant-test - # RGBA with 1BIT_ALPHA=YES - src_ds = gdal.Open("../gcore/data/stefan_full_rgba.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", src_ds, options=["1BIT_ALPHA=YES"] - ) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - ds = gdal.OpenEx( - "/vsimem/jp2lura_22.jp2", open_options=["1BIT_ALPHA_PROMOTION=NO"] - ) - fourth_band = ds.GetRasterBand(4) - assert fourth_band.GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "1" - ds = None - ds = gdal.Open("/vsimem/jp2lura_22.jp2") - assert ds.GetRasterBand(4).Checksum() == 23120 - ds = None - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - # RGBA with YCBCR420=YES - src_ds = gdal.Open("../gcore/data/stefan_full_rgba.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", src_ds, options=["YCBCR420=YES"] - ) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_22.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_RedBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(4).GetColorInterpretation() == gdal.GCI_AlphaBand - assert ds.GetRasterBand(1).Checksum() == 11457 - ds = None - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - # RGBA with YCC=YES. Will emit a warning for now because of OpenJPEG - # bug (only fixed in trunk, not released versions at that time) - src_ds = gdal.Open("../gcore/data/stefan_full_rgba.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", - src_ds, - options=["YCC=YES", "QUALITY=100", "REVERSIBLE=YES"], - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - # RGB,undefined - src_ds = gdal.Open("../gcore/data/stefan_full_rgba_photometric_rgb.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", src_ds, options=["QUALITY=100", "REVERSIBLE=YES"] - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_22.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_RedBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(4).GetColorInterpretation() == gdal.GCI_Undefined - ds = None - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - # RGB,undefined with ALPHA=YES - src_ds = gdal.Open("../gcore/data/stefan_full_rgba_photometric_rgb.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_22.jp2", - src_ds, - options=["QUALITY=100", "REVERSIBLE=YES", "ALPHA=YES"], - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_22.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_22.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_RedBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(4).GetColorInterpretation() == gdal.GCI_AlphaBand - ds = None - gdal.Unlink("/vsimem/jp2lura_22.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - -############################################################################### -# Test NBITS support - - -def DISABLED_jp2lura_23(): - - src_ds = gdal.Open("../gcore/data/uint16.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_23.jp2", - src_ds, - options=["NBITS=9", "QUALITY=100", "REVERSIBLE=YES"], - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - ds = gdal.Open("/vsimem/jp2lura_23.jp2") - assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "9" - - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_23_2.jp2", ds) - assert out_ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "9" - del out_ds - - ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_23.jp2.aux.xml") is None - gdal.Unlink("/vsimem/jp2lura_23.jp2") - gdal.Unlink("/vsimem/jp2lura_23_2.jp2") - - assert maxdiff <= 1, "Image too different from reference" - - -############################################################################### -# Test Grey+alpha support - - -def test_jp2lura_24(): - - # Grey+alpha - src_ds = gdal.Open("../gcore/data/stefan_full_greyalpha.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_24.jp2", src_ds, options=["REVERSIBLE=YES"] - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_24.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_24.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_GrayIndex - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_AlphaBand - ds = None - - assert ( - validate("/vsimem/jp2lura_24.jp2", expected_gmljp2=False, inspire_tg=False) - != "fail" - ) - - gdal.Unlink("/vsimem/jp2lura_24.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - if False: # pylint: disable=using-constant-test - # Grey+alpha with 1BIT_ALPHA=YES - src_ds = gdal.Open("../gcore/data/stefan_full_greyalpha.tif") - gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_24.jp2", src_ds, options=["1BIT_ALPHA=YES"] - ) - - src_ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_24.jp2.aux.xml") is None - ds = gdal.OpenEx( - "/vsimem/jp2lura_24.jp2", open_options=["1BIT_ALPHA_PROMOTION=NO"] - ) - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_GrayIndex - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_AlphaBand - assert ds.GetRasterBand(2).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "1" - ds = None - ds = gdal.Open("/vsimem/jp2lura_24.jp2") - assert ds.GetRasterBand(2).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") is None - assert ds.GetRasterBand(2).Checksum() == 23120 - ds = None - gdal.Unlink("/vsimem/jp2lura_24.jp2") - - -############################################################################### -# Test multiband support - - -def test_jp2lura_25(): - - src_ds = gdal.GetDriverByName("MEM").Create("", 100, 100, 5) - src_ds.GetRasterBand(1).Fill(255) - src_ds.GetRasterBand(2).Fill(250) - src_ds.GetRasterBand(3).Fill(245) - src_ds.GetRasterBand(4).Fill(240) - src_ds.GetRasterBand(5).Fill(235) - - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_25.jp2", src_ds, options=["REVERSIBLE=YES"] - ) - maxdiff = gdaltest.compare_ds(src_ds, out_ds) - del out_ds - src_ds = None - ds = gdal.Open("/vsimem/jp2lura_25.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_Undefined - ds = None - assert gdal.VSIStatL("/vsimem/jp2lura_25.jp2.aux.xml") is None - - gdal.Unlink("/vsimem/jp2lura_25.jp2") - - assert maxdiff <= 0, "Image too different from reference" - - -############################################################################### -# Test CreateCopy() from a JPEG2000 with a 2048x2048 tiling - - -def test_jp2lura_27(): - - # Test optimization in GDALCopyWholeRasterGetSwathSize() - # Not sure how we can check that except looking at logs with CPL_DEBUG=GDAL - # for "GDAL: GDALDatasetCopyWholeRaster(): 2048*2048 swaths, bInterleave=1" - src_ds = gdal.GetDriverByName("MEM").Create("", 2049, 2049, 4) - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_27.jp2", - src_ds, - options=["LEVELS=1", "TILEXSIZE=2048", "TILEYSIZE=2048"], - ) - src_ds = None - # print('End of JP2 decoding') - out2_ds = gdal.GetDriverByName("GTiff").CreateCopy( - "/vsimem/jp2lura_27.tif", out_ds, options=["TILED=YES"] - ) - out_ds = None - del out2_ds - gdal.Unlink("/vsimem/jp2lura_27.jp2") - gdal.Unlink("/vsimem/jp2lura_27.tif") - - -############################################################################### -# Test CODEBLOCK_WIDTH/_HEIGHT - - -XML_TYPE_IDX = 0 -XML_VALUE_IDX = 1 -XML_FIRST_CHILD_IDX = 2 - - -def find_xml_node(ar, element_name, only_attributes=False): - # type = ar[XML_TYPE_IDX] - value = ar[XML_VALUE_IDX] - if value == element_name: - return ar - for child_idx in range(XML_FIRST_CHILD_IDX, len(ar)): - child = ar[child_idx] - if only_attributes and child[XML_TYPE_IDX] != gdal.CXT_Attribute: - continue - found = find_xml_node(child, element_name) - if found is not None: - return found - return None - - -def get_attribute_val(ar, attr_name): - node = find_xml_node(ar, attr_name, True) - if node is None or node[XML_TYPE_IDX] != gdal.CXT_Attribute: - return None - if ( - len(ar) > XML_FIRST_CHILD_IDX - and node[XML_FIRST_CHILD_IDX][XML_TYPE_IDX] == gdal.CXT_Text - ): - return node[XML_FIRST_CHILD_IDX][XML_VALUE_IDX] - return None - - -def find_element_with_name(ar, element_name, name): - typ = ar[XML_TYPE_IDX] - value = ar[XML_VALUE_IDX] - if ( - typ == gdal.CXT_Element - and value == element_name - and get_attribute_val(ar, "name") == name - ): - return ar - for child_idx in range(XML_FIRST_CHILD_IDX, len(ar)): - child = ar[child_idx] - found = find_element_with_name(child, element_name, name) - if found: - return found - return None - - -def get_element_val(node): - if node is None: - return None - for child_idx in range(XML_FIRST_CHILD_IDX, len(node)): - child = node[child_idx] - if child[XML_TYPE_IDX] == gdal.CXT_Text: - return child[XML_VALUE_IDX] - return None - - -def jp2lura_test_codeblock(filename, codeblock_width, codeblock_height): - node = gdal.GetJPEG2000Structure(filename, ["ALL=YES"]) - xcb = 2 ** ( - 2 - + int( - get_element_val(find_element_with_name(node, "Field", "SPcod_xcb_minus_2")) - ) - ) - ycb = 2 ** ( - 2 - + int( - get_element_val(find_element_with_name(node, "Field", "SPcod_ycb_minus_2")) - ) - ) - if xcb != codeblock_width or ycb != codeblock_height: - return False - return True - - -def test_jp2lura_28(): - - src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10, 1) - - tests = [ - (["CODEBLOCK_WIDTH=2"], 64, 64, True), - (["CODEBLOCK_WIDTH=2048"], 64, 64, True), - (["CODEBLOCK_HEIGHT=2"], 64, 64, True), - (["CODEBLOCK_HEIGHT=2048"], 64, 64, True), - (["CODEBLOCK_WIDTH=128", "CODEBLOCK_HEIGHT=128"], 64, 64, True), - (["CODEBLOCK_WIDTH=63"], 32, 64, True), - (["CODEBLOCK_WIDTH=32", "CODEBLOCK_HEIGHT=32"], 32, 32, False), - ] - - for (options, expected_cbkw, expected_cbkh, warning_expected) in tests: - gdal.ErrorReset() - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_28.jp2", src_ds, options=options - ) - if warning_expected and gdal.GetLastErrorMsg() == "": - print(options) - pytest.fail("warning expected") - del out_ds - if not jp2lura_test_codeblock( - "/vsimem/jp2lura_28.jp2", expected_cbkw, expected_cbkh - ): - print(options) - pytest.fail("unexpected codeblock size") - - gdal.Unlink("/vsimem/jp2lura_28.jp2") - - -############################################################################### -# Test color table support - - -def test_jp2lura_30(): - - src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10, 1) - ct = gdal.ColorTable() - ct.SetColorEntry(0, (255, 255, 255, 255)) - ct.SetColorEntry(1, (255, 255, 0, 255)) - ct.SetColorEntry(2, (255, 0, 255, 255)) - ct.SetColorEntry(3, (0, 255, 255, 255)) - src_ds.GetRasterBand(1).SetRasterColorTable(ct) - - gdal.ErrorReset() - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_30.jp2", src_ds) - assert out_ds is None - - -############################################################################### -# Test unusual band color interpretation order - - -def DISABLED_jp2lura_31(): - - src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10, 3) - src_ds.GetRasterBand(1).SetColorInterpretation(gdal.GCI_GreenBand) - src_ds.GetRasterBand(2).SetColorInterpretation(gdal.GCI_BlueBand) - src_ds.GetRasterBand(3).SetColorInterpretation(gdal.GCI_RedBand) - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_31.jp2", src_ds) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_31.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_31.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_RedBand - ds = None - gdal.Unlink("/vsimem/jp2lura_31.jp2") - - # With alpha now - src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10, 4) - src_ds.GetRasterBand(1).SetColorInterpretation(gdal.GCI_AlphaBand) - src_ds.GetRasterBand(2).SetColorInterpretation(gdal.GCI_GreenBand) - src_ds.GetRasterBand(3).SetColorInterpretation(gdal.GCI_BlueBand) - src_ds.GetRasterBand(4).SetColorInterpretation(gdal.GCI_RedBand) - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_31.jp2", src_ds) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_31.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_31.jp2") - assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_AlphaBand - assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GreenBand - assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand - assert ds.GetRasterBand(4).GetColorInterpretation() == gdal.GCI_RedBand - ds = None - gdal.Unlink("/vsimem/jp2lura_31.jp2") - - -############################################################################### -# Test crazy tile size - - -def DISABLED_jp2lura_33(): - - src_ds = gdal.Open( - """ - - -""" - ) - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_33.jp2", - src_ds, - options=["BLOCKXSIZE=100000", "BLOCKYSIZE=100000"], - ) - assert out_ds is None - out_ds = None - gdal.Unlink("/vsimem/jp2lura_33.jp2") - - -############################################################################### -# Test opening a file whose dimensions are > 2^31-1 - - -def test_jp2lura_34(): - - with gdal.quiet_errors(): - ds = gdal.Open("data/jpeg2000/dimensions_above_31bit.jp2") - assert ds is None - - -############################################################################### -# Test opening a truncated file - - -def test_jp2lura_35(): - - with gdal.quiet_errors(): - ds = gdal.Open("data/jpeg2000/truncated.jp2") - assert ds is None - - -############################################################################### -# Test we cannot create files with more than 16384 bands - - -def test_jp2lura_36(): - - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2, 16385) - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_36.jp2", src_ds) - assert out_ds is None and gdal.VSIStatL("/vsimem/jp2lura_36.jp2") is None - - -############################################################################### -# Test metadata reading & writing - - -def test_jp2lura_37(): - - # No metadata - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=["WRITE_METADATA=YES"] - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - assert ds.GetMetadata() == {} - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Simple metadata in main domain - for options in [["WRITE_METADATA=YES"]]: - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - src_ds.SetMetadataItem("FOO", "BAR") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=options - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - assert ds.GetMetadata() == {"FOO": "BAR"} - ds = None - - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Simple metadata in auxiliary domain - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - src_ds.SetMetadataItem("FOO", "BAR", "SOME_DOMAIN") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=["WRITE_METADATA=YES"] - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - md = ds.GetMetadata("SOME_DOMAIN") - assert md == {"FOO": "BAR"} - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Simple metadata in auxiliary XML domain - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - src_ds.SetMetadata([""], "xml:SOME_DOMAIN") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=["WRITE_METADATA=YES"] - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - assert ds.GetMetadata("xml:SOME_DOMAIN")[0] == "\n" - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Special xml:BOX_ metadata domain - for options in [["WRITE_METADATA=YES"]]: - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - src_ds.SetMetadata([""], "xml:BOX_1") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=options - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - assert ds.GetMetadata("xml:BOX_0")[0] == "" - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Special xml:XMP metadata domain - for options in [["WRITE_METADATA=YES"]]: - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - src_ds.SetMetadata([""], "xml:XMP") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_37.jp2", src_ds, options=options - ) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_37.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/jp2lura_37.jp2") - assert ds.GetMetadata("xml:XMP")[0] == "" - ds = None - - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - # Special xml:IPR metadata domain - # for options in [ ['WRITE_METADATA=YES'] ]: - # src_ds = gdal.GetDriverByName('MEM').Create('', 2, 2) - # src_ds.SetMetadata( [ '' ], 'xml:IPR') - # out_ds = gdaltest.jp2lura_drv.CreateCopy('/vsimem/jp2lura_37.jp2', src_ds, options = options) - # del out_ds - # if gdal.VSIStatL('/vsimem/jp2lura_37.jp2.aux.xml') is not None: - # gdaltest.post_reason('fail') - # return 'fail' - # ds = gdal.Open('/vsimem/jp2lura_37.jp2') - # if ds.GetMetadata('xml:IPR')[0] != '': - # gdaltest.post_reason('fail') - # return 'fail' - # ds = None - - gdal.Unlink("/vsimem/jp2lura_37.jp2") - - -############################################################################### -# Test non-EPSG SRS (so written with a GML dictionary) - - -def test_jp2lura_38(): - - # No metadata - src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) - wkt = """PROJCS["UTM Zone 31, Northern Hemisphere",GEOGCS["unnamed ellipse",DATUM["unknown",SPHEROID["unnamed",100,1]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]""" - src_ds.SetProjection(wkt) - src_ds.SetGeoTransform([0, 60, 0, 0, 0, -60]) - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_38.jp2", src_ds, options=["GeoJP2=NO"] - ) - assert out_ds.GetProjectionRef() == wkt - crsdictionary = out_ds.GetMetadata_List("xml:CRSDictionary.gml")[0] - out_ds = None - gdal.Unlink("/vsimem/jp2lura_38.jp2") - - do_validate = False - try: - import xmlvalidate - - do_validate = True - except ImportError: - print("Cannot import xmlvalidate") - - try: - os.stat("tmp/cache/SCHEMAS_OPENGIS_NET") - except OSError: - do_validate = False - - if do_validate: - assert xmlvalidate.validate( - crsdictionary, ogc_schemas_location="tmp/cache/SCHEMAS_OPENGIS_NET" - ) - - -############################################################################### -# Test GMLJP2OVERRIDE configuration option and DGIWG GMLJP2 - - -def test_jp2lura_39(): - - # No metadata - src_ds = gdal.GetDriverByName("MEM").Create("", 20, 20) - src_ds.SetGeoTransform([0, 60, 0, 0, 0, -60]) - gdal.SetConfigOption("GMLJP2OVERRIDE", "/vsimem/override.gml") - # This GML has srsName only on RectifiedGrid (taken from D.2.2.2 from DGIWG_Profile_of_JPEG2000_for_Georeferenced_Imagery.pdf) - gdal.FileFromMemBuffer( - "/vsimem/override.gml", - """ - - - - - - - - - - - - 0 0 - 4999 9999 - - - X - Y - - - - 19.1234567 37.1234567 - - - - 0.0 0.00001234 - -0.00001234 0.0 - - - - - - - gmljp2://codestream/0 - Record Interleaved - - - - - - -""", - ) - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_39.jp2", src_ds, options=["GeoJP2=NO"] - ) - gdal.SetConfigOption("GMLJP2OVERRIDE", None) - gdal.Unlink("/vsimem/override.gml") - del out_ds - ds = gdal.Open("/vsimem/jp2lura_39.jp2") - assert ds.GetProjectionRef().find("4326") >= 0 - ds = None - gdal.Unlink("/vsimem/jp2lura_39.jp2") - - -############################################################################### -# Test we can parse GMLJP2 v2.0 - - -def test_jp2lura_40(): - - # No metadata - src_ds = gdal.GetDriverByName("MEM").Create("", 20, 20) - src_ds.SetGeoTransform([0, 60, 0, 0, 0, -60]) - - gdal.FileFromMemBuffer( - "/vsimem/override.gml", - """ - - - - - - - gmljp2://codestream - inapplicable - - - - - - - - - - 0 0 - 19 19 - - - Lat Long - - - 48.95 2.05 - - - 0 0.1 - -0.1 0 - - - - - - gmljp2://codestream - inapplicable - - - - - -""", - ) - - with gdal.config_option("GMLJP2OVERRIDE", "/vsimem/override.gml"): - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_40.jp2", src_ds, options=["GeoJP2=NO"] - ) - gdal.Unlink("/vsimem/override.gml") - del out_ds - ds = gdal.Open("/vsimem/jp2lura_40.jp2") - assert ds.GetProjectionRef().find("4326") >= 0 - got_gt = ds.GetGeoTransform() - expected_gt = (2, 0.1, 0, 49, 0, -0.1) - for i in range(6): - assert got_gt[i] == pytest.approx(expected_gt[i], abs=1e-5) - ds = None - gdal.Unlink("/vsimem/jp2lura_40.jp2") - - -############################################################################### -# Test USE_SRC_CODESTREAM=YES - - -def test_jp2lura_41(): - - src_ds = gdal.Open("data/jpeg2000/byte.jp2") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_41.jp2", - src_ds, - options=[ - "USE_SRC_CODESTREAM=YES", - "@PROFILE=PROFILE_1", - "GEOJP2=NO", - "GMLJP2=NO", - ], - ) - assert src_ds.GetRasterBand(1).Checksum() == out_ds.GetRasterBand(1).Checksum() - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_41.jp2").size == 9923 - gdal.Unlink("/vsimem/jp2lura_41.jp2") - gdal.Unlink("/vsimem/jp2lura_41.jp2.aux.xml") - - # Warning if ignored option - gdal.ErrorReset() - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_41.jp2", - src_ds, - options=["USE_SRC_CODESTREAM=YES", "QUALITY=1"], - ) - del out_ds - # if gdal.GetLastErrorMsg() == '': - # gdaltest.post_reason('fail') - # return 'fail' - gdal.Unlink("/vsimem/jp2lura_41.jp2") - gdal.Unlink("/vsimem/jp2lura_41.jp2.aux.xml") - - # Warning if source is not JPEG2000 - src_ds = gdal.Open("data/byte.tif") - gdal.ErrorReset() - with gdal.quiet_errors(): - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_41.jp2", src_ds, options=["USE_SRC_CODESTREAM=YES"] - ) - del out_ds - assert gdal.GetLastErrorMsg() != "" - gdal.Unlink("/vsimem/jp2lura_41.jp2") - - -############################################################################### -# Get structure of a JPEG2000 file - - -def test_jp2lura_43(): - - ret = gdal.GetJPEG2000StructureAsString("data/jpeg2000/byte.jp2", ["ALL=YES"]) - assert ret is not None - - -############################################################################### -# Test GMLJP2v2 - - -@pytest.mark.require_driver("GML") -@pytest.mark.skipif( - gdal.GetDriverByName("KML") is None and gdal.GetDriverByName("LIBKML") is None, - reason="KML or LIBKML driver missing", -) -def test_jp2lura_45(): - - # Test GMLJP2V2_DEF=YES - src_ds = gdal.Open("data/byte.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_45.jp2", src_ds, options=["GMLJP2V2_DEF=YES"] - ) - assert out_ds.GetLayerCount() == 0 - assert out_ds.GetLayer(0) is None - del out_ds - - ds = gdal.Open("/vsimem/jp2lura_45.jp2") - gmljp2 = ds.GetMetadata_List("xml:gml.root-instance")[0] - minimal_instance = """ - - - - - inapplicable - - - - - - - - - - - - 440720 3750120 - 441920 3751320 - - - - - - - 0 0 - 19 19 - - - x - y - - - 440750 3751290 - - - 60 0 - 0 -60 - - - - - - gmljp2://codestream/0 - inapplicable - - - - - - -""" - assert gmljp2 == minimal_instance - - gdal.Unlink("/vsimem/jp2lura_45.jp2") - - -############################################################################### -# Test writing & reading RPC in GeoJP2 box - - -def test_jp2lura_47(): - - src_ds = gdal.Open("../gcore/data/byte_rpc.tif") - out_ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_47.jp2", src_ds) - del out_ds - assert gdal.VSIStatL("/vsimem/jp2lura_47.jp2.aux.xml") is None - - ds = gdal.Open("/vsimem/jp2lura_47.jp2") - assert ds.GetMetadata("RPC") is not None - ds = None - - gdal.Unlink("/vsimem/jp2lura_47.jp2") - - -############################################################################### -# Test reading a dataset whose tile dimensions are larger than dataset ones - - -def test_jp2lura_48(): - - ds = gdal.Open("data/jpeg2000/byte_tile_2048.jp2") - (blockxsize, blockysize) = ds.GetRasterBand(1).GetBlockSize() - assert (blockxsize, blockysize) == (20, 20) - assert ds.GetRasterBand(1).Checksum() == 4610 - ds = None - - -############################################################################### - - -def test_jp2lura_online_1(): - - gdaltest.download_or_skip( - "http://download.osgeo.org/gdal/data/jpeg2000/7sisters200.j2k", - "7sisters200.j2k", - ) - - # Checksum = 32669 on my PC - tst = gdaltest.GDALTest( - "JP2Lura", "tmp/cache/7sisters200.j2k", 1, None, filename_absolute=1 - ) - - tst.testOpen() - - ds = gdal.Open("tmp/cache/7sisters200.j2k") - ds.GetRasterBand(1).Checksum() - ds = None - - -############################################################################### - - -def test_jp2lura_online_2(): - - gdaltest.download_or_skip( - "http://download.osgeo.org/gdal/data/jpeg2000/gcp.jp2", "gcp.jp2" - ) - - # Checksum = 15621 on my PC - tst = gdaltest.GDALTest( - "JP2Lura", "tmp/cache/gcp.jp2", 1, None, filename_absolute=1 - ) - - tst.testOpen() - - ds = gdal.Open("tmp/cache/gcp.jp2") - ds.GetRasterBand(1).Checksum() - assert len(ds.GetGCPs()) == 15, "bad number of GCP" - - expected_wkt = """GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]""" - assert ds.GetGCPProjection() == expected_wkt, "bad GCP projection" - - ds = None - - -############################################################################### - - -def test_jp2lura_online_3(): - - gdaltest.download_or_skip( - "http://www.openjpeg.org/samples/Bretagne1.j2k", "Bretagne1.j2k" - ) - - gdaltest.download_or_skip( - "http://www.openjpeg.org/samples/Bretagne1.bmp", "Bretagne1.bmp" - ) - - tst = gdaltest.GDALTest( - "JP2Lura", "tmp/cache/Bretagne1.j2k", 1, None, filename_absolute=1 - ) - - tst.testOpen() - - ds = gdal.Open("tmp/cache/Bretagne1.j2k") - ds_ref = gdal.Open("tmp/cache/Bretagne1.bmp") - maxdiff = gdaltest.compare_ds(ds, ds_ref) - print(ds.GetRasterBand(1).Checksum()) - print(ds_ref.GetRasterBand(1).Checksum()) - - ds = None - ds_ref = None - - # Difference between the image before and after compression - assert maxdiff <= 17, "Image too different from reference" - - -############################################################################### - - -def test_jp2lura_online_4(): - - gdaltest.download_or_skip( - "http://www.openjpeg.org/samples/Bretagne2.j2k", "Bretagne2.j2k" - ) - - gdaltest.download_or_skip( - "http://www.openjpeg.org/samples/Bretagne2.bmp", "Bretagne2.bmp" - ) - - tst = gdaltest.GDALTest( - "JP2Lura", "tmp/cache/Bretagne2.j2k", 1, None, filename_absolute=1 - ) - - tst.testOpen() - - ds = gdal.Open("tmp/cache/Bretagne2.j2k") - ds_ref = gdal.Open("tmp/cache/Bretagne2.bmp") - maxdiff = gdaltest.compare_ds(ds, ds_ref, 0, 0, 1024, 1024) - print(ds.GetRasterBand(1).Checksum()) - print(ds_ref.GetRasterBand(1).Checksum()) - - ds = None - ds_ref = None - - # Difference between the image before and after compression - assert maxdiff <= 10, "Image too different from reference" - - -############################################################################### -# Try reading JP2Lura with color table - - -def test_jp2lura_online_5(): - - gdaltest.download_or_skip( - "http://www.gwg.nga.mil/ntb/baseline/software/testfile/Jpeg2000/jp2_09/file9.jp2", - "file9.jp2", - ) - - ds = gdal.Open("tmp/cache/file9.jp2") - cs1 = ds.GetRasterBand(1).Checksum() - assert cs1 == 47664, "Did not get expected checksums" - assert ( - ds.GetRasterBand(1).GetColorTable() is not None - ), "Did not get expected color table" - ds = None - - -############################################################################### -# Try reading YCbCr JP2Lura as RGB - - -def test_jp2lura_online_6(): - - gdaltest.download_or_skip( - "http://www.gwg.nga.mil/ntb/baseline/software/testfile/Jpeg2000/jp2_03/file3.jp2", - "file3.jp2", - ) - - ds = gdal.Open("tmp/cache/file3.jp2") - # cs1 = ds.GetRasterBand(1).Checksum() - # cs2 = ds.GetRasterBand(2).Checksum() - # cs3 = ds.GetRasterBand(3).Checksum() - # if cs1 != 26140 or cs2 != 32689 or cs3 != 48247: - # print(cs1, cs2, cs3) - # gdaltest.post_reason('Did not get expected checksums') - # return 'fail' - assert ds is None - ds = None - - -############################################################################### -# Test GDAL_GEOREF_SOURCES - - -def test_jp2lura_49(): - - tests = [ - (None, True, True, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - (None, True, False, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - (None, False, True, "", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - (None, False, False, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ("INTERNAL", True, True, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ( - "INTERNAL,PAM", - True, - True, - 'LOCAL_CS["PAM"]', - (100.0, 1.0, 0.0, 300.0, 0.0, -1.0), - ), - ("INTERNAL,WORLDFILE", True, True, "", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - ( - "INTERNAL,PAM,WORLDFILE", - True, - True, - 'LOCAL_CS["PAM"]', - (100.0, 1.0, 0.0, 300.0, 0.0, -1.0), - ), - ( - "INTERNAL,WORLDFILE,PAM", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ("WORLDFILE,PAM,INTERNAL", False, False, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ("PAM,WORLDFILE,INTERNAL", False, False, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ("PAM", True, True, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - ( - "PAM,WORLDFILE", - True, - True, - 'LOCAL_CS["PAM"]', - (100.0, 1.0, 0.0, 300.0, 0.0, -1.0), - ), - ("WORLDFILE", True, True, "", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - ( - "WORLDFILE,PAM", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ("WORLDFILE,INTERNAL", True, True, "", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - ( - "WORLDFILE,PAM,INTERNAL", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ( - "WORLDFILE,INTERNAL,PAM", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ("NONE", True, True, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ] - - for ( - config_option_value, - copy_pam, - copy_worldfile, - expected_srs, - expected_gt, - ) in tests: - with gdal.config_option("GDAL_GEOREF_SOURCES", config_option_value): - gdal.FileFromMemBuffer( - "/vsimem/byte_nogeoref.jp2", - open("data/jpeg2000/byte_nogeoref.jp2", "rb").read(), - ) - if copy_pam: - gdal.FileFromMemBuffer( - "/vsimem/byte_nogeoref.jp2.aux.xml", - open("data/jpeg2000/byte_nogeoref.jp2.aux.xml", "rb").read(), - ) - if copy_worldfile: - gdal.FileFromMemBuffer( - "/vsimem/byte_nogeoref.j2w", - open("data/jpeg2000/byte_nogeoref.j2w", "rb").read(), - ) - ds = gdal.Open("/vsimem/byte_nogeoref.jp2") - gt = ds.GetGeoTransform() - srs_wkt = ds.GetProjectionRef() - ds = None - gdal.Unlink("/vsimem/byte_nogeoref.jp2") - gdal.Unlink("/vsimem/byte_nogeoref.jp2.aux.xml") - gdal.Unlink("/vsimem/byte_nogeoref.j2w") - - if gt != expected_gt: - print("Got " + str(gt)) - print("Expected " + str(expected_gt)) - pytest.fail( - "Did not get expected gt for %s,copy_pam=%s,copy_worldfile=%s" - % (config_option_value, str(copy_pam), str(copy_worldfile)) - ) - - if ( - expected_srs == 'LOCAL_CS["PAM"]' - and srs_wkt - == 'LOCAL_CS["PAM",UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]' - ): - pass # ok - elif (expected_srs == "" and srs_wkt != "") or ( - expected_srs != "" and expected_srs not in srs_wkt - ): - print("Got " + srs_wkt) - print("Expected " + expected_srs) - pytest.fail( - "Did not get expected SRS for %s,copy_pam=%s,copy_worldfile=%s" - % (config_option_value, str(copy_pam), str(copy_worldfile)) - ) - - tests = [ - (None, True, True, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - (None, True, False, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - (None, False, True, "26711", (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0)), - (None, False, False, "26711", (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0)), - ("INTERNAL", True, True, "26711", (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0)), - ( - "INTERNAL,PAM", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ( - "INTERNAL,WORLDFILE", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ( - "INTERNAL,PAM,WORLDFILE", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ( - "INTERNAL,WORLDFILE,PAM", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ( - "WORLDFILE,PAM,INTERNAL", - False, - False, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ( - "PAM,WORLDFILE,INTERNAL", - False, - False, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ("GEOJP2", True, True, "26711", (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0)), - ( - "GEOJP2,GMLJP2", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ("GMLJP2", True, True, "26712", (439970.0, 60.0, 0.0, 3751030.0, 0.0, -60.0)), - ( - "GMLJP2,GEOJP2", - True, - True, - "26712", - (439970.0, 60.0, 0.0, 3751030.0, 0.0, -60.0), - ), - ("MSIG", True, True, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ( - "MSIG,GMLJP2,GEOJP2", - True, - True, - "26712", - (439970.0, 60.0, 0.0, 3751030.0, 0.0, -60.0), - ), - ( - "MSIG,GEOJP2,GMLJP2", - True, - True, - "26711", - (440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0), - ), - ("PAM", True, True, 'LOCAL_CS["PAM"]', (100.0, 1.0, 0.0, 300.0, 0.0, -1.0)), - ( - "PAM,WORLDFILE", - True, - True, - 'LOCAL_CS["PAM"]', - (100.0, 1.0, 0.0, 300.0, 0.0, -1.0), - ), - ("WORLDFILE", True, True, "", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - ( - "WORLDFILE,PAM", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ("WORLDFILE,INTERNAL", True, True, "26711", (99.5, 1.0, 0.0, 200.5, 0.0, -1.0)), - ( - "WORLDFILE,PAM,INTERNAL", - True, - True, - 'LOCAL_CS["PAM"]', - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ( - "WORLDFILE,INTERNAL,PAM", - True, - True, - "26711", - (99.5, 1.0, 0.0, 200.5, 0.0, -1.0), - ), - ("NONE", True, True, "", (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)), - ] - - for ( - config_option_value, - copy_pam, - copy_worldfile, - expected_srs, - expected_gt, - ) in tests: - gdal.FileFromMemBuffer( - "/vsimem/inconsitant_geojp2_gmljp2.jp2", - open("data/jpeg2000/inconsitant_geojp2_gmljp2.jp2", "rb").read(), - ) - if copy_pam: - gdal.FileFromMemBuffer( - "/vsimem/inconsitant_geojp2_gmljp2.jp2.aux.xml", - open( - "data/jpeg2000/inconsitant_geojp2_gmljp2.jp2.aux.xml", "rb" - ).read(), - ) - if copy_worldfile: - gdal.FileFromMemBuffer( - "/vsimem/inconsitant_geojp2_gmljp2.j2w", - open("data/jpeg2000/inconsitant_geojp2_gmljp2.j2w", "rb").read(), - ) - open_options = [] - if config_option_value is not None: - open_options += ["GEOREF_SOURCES=" + config_option_value] - ds = gdal.OpenEx( - "/vsimem/inconsitant_geojp2_gmljp2.jp2", open_options=open_options - ) - gt = ds.GetGeoTransform() - srs_wkt = ds.GetProjectionRef() - ds = None - gdal.Unlink("/vsimem/inconsitant_geojp2_gmljp2.jp2") - gdal.Unlink("/vsimem/inconsitant_geojp2_gmljp2.jp2.aux.xml") - gdal.Unlink("/vsimem/inconsitant_geojp2_gmljp2.j2w") - - if gt != expected_gt: - print("Got " + str(gt)) - print("Expected " + str(expected_gt)) - pytest.fail( - "Did not get expected gt for %s,copy_pam=%s,copy_worldfile=%s" - % (config_option_value, str(copy_pam), str(copy_worldfile)) - ) - - if ( - expected_srs == 'LOCAL_CS["PAM"]' - and srs_wkt - == 'LOCAL_CS["PAM",UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]' - ): - pass # ok - elif (expected_srs == "" and srs_wkt != "") or ( - expected_srs != "" and expected_srs not in srs_wkt - ): - print("Got " + srs_wkt) - print("Expected " + expected_srs) - pytest.fail( - "Did not get expected SRS for %s,copy_pam=%s,copy_worldfile=%s" - % (config_option_value, str(copy_pam), str(copy_worldfile)) - ) - - ds = gdal.OpenEx( - "data/jpeg2000/inconsitant_geojp2_gmljp2.jp2", - open_options=["GEOREF_SOURCES=PAM,WORLDFILE"], - ) - fl = ds.GetFileList() - assert set(fl) == set( - [ - "data/jpeg2000/inconsitant_geojp2_gmljp2.jp2", - "data/jpeg2000/inconsitant_geojp2_gmljp2.jp2.aux.xml", - ] - ), "Did not get expected filelist" - - gdal.ErrorReset() - with gdal.quiet_errors(): - gdal.OpenEx( - "data/jpeg2000/inconsitant_geojp2_gmljp2.jp2", - open_options=["GEOREF_SOURCES=unhandled"], - ) - assert gdal.GetLastErrorMsg() != "", "expected warning" - - -############################################################################### -# Test reading split IEEE-754 Float32 - - -def test_jp2lura_50(): - - tst = gdaltest.GDALTest( - "JP2Lura", "jpeg2000/float32_ieee754_split_reversible.jp2", 1, 4672 - ) - tst.testOpen() - - -############################################################################### -# Test split IEEE-754 Float32 - - -def test_jp2lura_51(): - - # Don't allow it by default - src_ds = gdal.Open("data/float32.tif") - with gdal.quiet_errors(): - ds = gdaltest.jp2lura_drv.CreateCopy("/vsimem/jp2lura_51.jp2", src_ds) - assert ds is None - - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_51.jp2", src_ds, options=["SPLIT_IEEE754=YES"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - - assert validate("/vsimem/jp2lura_51.jp2", inspire_tg=False) != "fail" - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_51.jp2") - - assert maxdiff <= 0.01 - - # QUALITY - with gdal.quiet_errors(): - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_51.jp2", - src_ds, - options=["SPLIT_IEEE754=YES", "QUALITY=100"], - ) - if ds is not None: - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 124 - - assert validate("/vsimem/jp2lura_51.jp2", inspire_tg=False) != "fail" - ds = None - with gdal.quiet_errors(): - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_51.jp2") - gdal.Unlink("/vsimem/jp2lura_51.jp2") - - # RATE - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_51.jp2", src_ds, options=["SPLIT_IEEE754=YES", "RATE=1"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 370 - - assert validate("/vsimem/jp2lura_51.jp2", inspire_tg=False) != "fail" - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_51.jp2") - - # Test reversible - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_51.jp2", - src_ds, - options=["SPLIT_IEEE754=YES", "REVERSIBLE=YES"], - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff == 0.0 - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_51.jp2") - - -############################################################################### -# Test other data types - - -def test_jp2lura_52(): - - tests = [ - [-32768, gdal.GDT_Int16, "h"], - [-1, gdal.GDT_Int16, "h"], - [32767, gdal.GDT_Int16, "h"], - [0, gdal.GDT_UInt16, "H"], - [65535, gdal.GDT_UInt16, "H"], - [-(2**27), gdal.GDT_Int32, "i"], - [2**27 - 1, gdal.GDT_Int32, "i"], - [0, gdal.GDT_UInt32, "I"], - [2**28 - 1, gdal.GDT_UInt32, "I"], - ] - for (val, dt, fmt) in tests: - - src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10, 1, dt) - src_ds.GetRasterBand(1).Fill(val) - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_52.jp2", src_ds, options=["REVERSIBLE=YES"] - ) - got_min, got_max = ds.GetRasterBand(1).ComputeRasterMinMax() - assert val == got_min and val == got_max, (val, dt, fmt, got_min, got_max) - ds = None - - assert not ( - val >= 0 - and validate( - "/vsimem/jp2lura_52.jp2", expected_gmljp2=False, inspire_tg=False - ) - == "fail" - ), (val, dt, fmt) - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_52.jp2") - - -############################################################################### -# Test RATE and QUALITY - - -def test_jp2lura_53(): - - src_ds = gdal.Open("data/byte.tif") - - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_53.jp2", src_ds, options=["RATE=1"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 8 - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_53.jp2") - - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_53.jp2", src_ds, options=["QUALITY=100"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 2 - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_53.jp2") - - # Forcing irreversible due to RATE - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_53.jp2", src_ds, options=["REVERSIBLE=YES", "RATE=1"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 8 - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_53.jp2") - - # QUALITY ignored - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_53.jp2", src_ds, options=["REVERSIBLE=YES", "QUALITY=100"] - ) - maxdiff = gdaltest.compare_ds(ds, src_ds) - ds = None - assert maxdiff <= 0 - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_53.jp2") - - -############################################################################### -# Test RasterIO edge cases - - -def test_jp2lura_54(): - - # Tiled with incomplete boundary tiles - src_ds = gdal.GetDriverByName("MEM").Create("", 100, 100, 1) - src_ds.GetRasterBand(1).Fill(100) - ds = gdaltest.jp2lura_drv.CreateCopy( - "/vsimem/jp2lura_54.jp2", - src_ds, - options=["REVERSIBLE=YES", "TILEXSIZE=64", "TILEYSIZE=64"], - ) - # Request with a type that is not the natural type - data = ds.GetRasterBand(1).ReadRaster( - 0, 0, 100, 100, 100, 100, buf_type=gdal.GDT_Int16 - ) - data = struct.unpack("h" * 100 * 100, data) - assert min(data) == 100 and max(data) == 100 - - # Request at a resolution that is not a power of two - data = ds.GetRasterBand(1).ReadRaster(0, 0, 100, 100, 30, 30) - data = struct.unpack("B" * 30 * 30, data) - assert min(data) == 100 and max(data) == 100 - - ds = None - - gdaltest.jp2lura_drv.Delete("/vsimem/jp2lura_54.jp2") diff --git a/autotest/gdrivers/jp2metadata.py b/autotest/gdrivers/jp2metadata.py index d560247629bf..a981c3138dec 100755 --- a/autotest/gdrivers/jp2metadata.py +++ b/autotest/gdrivers/jp2metadata.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -38,7 +22,7 @@ def have_jpeg2000_capable_driver(): # JP2MrSID doesn't manage to open data/jpeg2000/IMG_md_ple_R1C1.jp2 - for drv_name in ["JP2KAK", "JP2LURA", "JP2ECW", "JP2OpenJPEG"]: + for drv_name in ["JP2KAK", "JP2ECW", "JP2OpenJPEG"]: if gdal.GetDriverByName(drv_name): return True return False diff --git a/autotest/gdrivers/jp2openjpeg.py b/autotest/gdrivers/jp2openjpeg.py index 46820ee810e7..1aa3439bba66 100755 --- a/autotest/gdrivers/jp2openjpeg.py +++ b/autotest/gdrivers/jp2openjpeg.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -389,6 +373,10 @@ def test_jp2openjpeg_12(): # Check that PAM overrides internal GCPs (#5279) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_jp2openjpeg_13(): # Create a dataset with GCPs @@ -1446,6 +1434,10 @@ def test_jp2openjpeg_32(): # Test crazy tile size +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_jp2openjpeg_33(): src_ds = gdal.Open( @@ -2744,10 +2736,10 @@ def test_jp2openjpeg_45(): ) del out_ds - dircontent = gdal.ReadDir("/vsimem/") + dircontent = gdal.ReadDir("/vsimem/.#!HIDDEN!#.") if dircontent: for filename in dircontent: - assert not filename.startswith("gmljp2") + assert "gmljp2" not in filename ds = ogr.Open("/vsimem/jp2openjpeg_45.jp2") assert ds.GetLayerCount() == 1 @@ -3818,6 +3810,10 @@ def test_jp2openjpeg_mosaic(): @pytest.mark.require_curl() +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_jp2openjpeg_vrt_protocol(): (webserver_process, webserver_port) = webserver.launch( @@ -3924,3 +3920,29 @@ def test_jp2openjpeg_unsupported_srs_for_gmljp2(tmp_vsimem): assert ds.GetSpatialRef().IsSame(ref_srs) # Check that we do *not* have a GMLJP2 box assert "xml:gml.root-instance" not in ds.GetMetadataDomainList() + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. +# (might be risky depending on libopenjp2...) + + +@pytest.mark.parametrize( + "src_filename,creation_options", + [ + # Created with gdal_translate autotest/gcore/data/byte.tif autotest/gdrivers/data/jpeg2000/byte_lossless_openjp2_golden.jp2 -of jp2openjpeg -co QUALITY=100 -co REVERSIBLE=YES -co COMMENT= + ( + "data/jpeg2000/byte_lossless_openjp2_golden.jp2", + ["QUALITY=100", "REVERSIBLE=YES", "COMMENT="], + ), + ], +) +def test_jp2openjpeg_write_check_golden_file(tmp_path, src_filename, creation_options): + + out_filename = str(tmp_path / "test.jp2") + with gdal.Open(src_filename) as src_ds: + gdal.GetDriverByName("JP2OpenJPEG").CreateCopy( + out_filename, src_ds, options=creation_options + ) + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size + assert open(src_filename, "rb").read() == open(out_filename, "rb").read() diff --git a/autotest/gdrivers/jpeg.py b/autotest/gdrivers/jpeg.py index 2dae55fe1e1d..1afece500db4 100755 --- a/autotest/gdrivers/jpeg.py +++ b/autotest/gdrivers/jpeg.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -800,6 +784,10 @@ def test_jpeg_mask_lsb_order_issue_4351(): # Test correct GCP reading with PAM (#5352) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_jpeg_20(): src_ds = gdal.Open("data/rgb_gcp.vrt") diff --git a/autotest/gdrivers/jpegxl.py b/autotest/gdrivers/jpegxl.py index 4ae20bcfa469..e02a40992155 100755 --- a/autotest/gdrivers/jpegxl.py +++ b/autotest/gdrivers/jpegxl.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import base64 @@ -143,7 +127,7 @@ def test_jpegxl_rgba_distance(): @pytest.mark.parametrize( - "quality,equivalent_distance", [(100, 0), (90, 1), (10, 12.65)] + "quality,equivalent_distance", [(100, 0), (10, 15.266666666666667)] ) def test_jpegxl_rgba_quality(quality, equivalent_distance): @@ -568,6 +552,24 @@ def test_jpegxl_write_five_bands(): gdal.GetDriverByName("JPEGXL").Delete(outfilename) +def test_jpegxl_write_five_bands_lossy(): + + drv = gdal.GetDriverByName("JPEGXL") + if drv.GetMetadataItem("JXL_ENCODER_SUPPORT_EXTRA_CHANNELS") is None: + pytest.skip() + + src_ds = gdal.Open("data/jpegxl/five_bands.jxl") + outfilename = "/vsimem/out.jxl" + gdal.Translate(outfilename, src_ds, options="-of JPEGXL -co DISTANCE=3 -ot Byte") + ds = gdal.Open(outfilename) + for i in range(5): + assert ds.GetRasterBand(i + 1).ComputeRasterMinMax() == pytest.approx( + (10.0 * (i + 1), 10.0 * (i + 1)), abs=1 + ) + ds = None + gdal.GetDriverByName("JPEGXL").Delete(outfilename) + + def test_jpegxl_createcopy_errors(): outfilename = "/vsimem/out.jxl" @@ -845,3 +847,17 @@ def test_jpegxl_identify_raw_codestream(): f"{gdalmanage_path} identify data/jpegxl/test.jxl.bin" ) assert "JPEGXL" in out + + +############################################################################### +def test_jpegxl_read_float16(): + + # Image produced with: + # gdal_translate autotest/gcore/data/rgbsmall.tif float.exr -co PIXEL_TYPE=FLOAT -co TILED=NO -co COMPRESS=PIZ + # cjxl -d 0 float.exr float16.jxl + ds = gdal.Open("data/jpegxl/float16.jxl") + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 21212, + 21053, + 21349, + ] diff --git a/autotest/gdrivers/jpipkak.py b/autotest/gdrivers/jpipkak.py index 027e835aebed..859bcffdc92b 100755 --- a/autotest/gdrivers/jpipkak.py +++ b/autotest/gdrivers/jpipkak.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/kea.py b/autotest/gdrivers/kea.py index a6a6d0c224c1..8f69cf943015 100755 --- a/autotest/gdrivers/kea.py +++ b/autotest/gdrivers/kea.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/kmlsuperoverlay.py b/autotest/gdrivers/kmlsuperoverlay.py index 11cfb79e7fa1..4f71b22d539f 100755 --- a/autotest/gdrivers/kmlsuperoverlay.py +++ b/autotest/gdrivers/kmlsuperoverlay.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -127,6 +111,10 @@ def test_kmlsuperoverlay_3(): # Test overviews +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_kmlsuperoverlay_4(): vrt_xml = """ @@ -231,6 +219,10 @@ def test_kmlsuperoverlay_4(): # Test that a raster which crosses the anti-meridian will be able to be displayed correctly (#4528) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_kmlsuperoverlay_5(): from xml.etree import ElementTree @@ -398,6 +390,10 @@ def test_kmlsuperoverlay_gx_latlonquad(): # KML/PNG files in transparent areas +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_kmlsuperoverlay_8(): # a large raster with actual data on each end and blank space in between diff --git a/autotest/gdrivers/kro.py b/autotest/gdrivers/kro.py index a7093b467b9c..fe10bd74bbf1 100755 --- a/autotest/gdrivers/kro.py +++ b/autotest/gdrivers/kro.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/ktx2.py b/autotest/gdrivers/ktx2.py index a86645368649..2162d942a88d 100755 --- a/autotest/gdrivers/ktx2.py +++ b/autotest/gdrivers/ktx2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/l1b.py b/autotest/gdrivers/l1b.py index a249373021c9..fcc6dca84cc4 100755 --- a/autotest/gdrivers/l1b.py +++ b/autotest/gdrivers/l1b.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/lan.py b/autotest/gdrivers/lan.py index 9b3d9c9ef4ea..af971d9433eb 100755 --- a/autotest/gdrivers/lan.py +++ b/autotest/gdrivers/lan.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/lcp.py b/autotest/gdrivers/lcp.py index 0374a0362f33..20a72dcabaaf 100755 --- a/autotest/gdrivers/lcp.py +++ b/autotest/gdrivers/lcp.py @@ -10,23 +10,7 @@ # Copyright (c) 2008-2009, Even Rouault # Copyright (c) 2013, Kyle Shannon # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/gdrivers/leveller.py b/autotest/gdrivers/leveller.py index 2a88e5e89f0d..800d5a58938c 100755 --- a/autotest/gdrivers/leveller.py +++ b/autotest/gdrivers/leveller.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2005, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/loslas.py b/autotest/gdrivers/loslas.py index b7e4b1b3e6a6..306521139612 100755 --- a/autotest/gdrivers/loslas.py +++ b/autotest/gdrivers/loslas.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/mbtiles.py b/autotest/gdrivers/mbtiles.py index c52898067ec9..50f0b3feb64e 100755 --- a/autotest/gdrivers/mbtiles.py +++ b/autotest/gdrivers/mbtiles.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/gdrivers/mem.py b/autotest/gdrivers/mem.py index 09a3233f9c65..878155dda27b 100755 --- a/autotest/gdrivers/mem.py +++ b/autotest/gdrivers/mem.py @@ -10,23 +10,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ctypes @@ -83,8 +67,7 @@ def test_mem_1(): ####################################################### # Setup dataset drv = gdal.GetDriverByName("MEM") - gdaltest.mem_ds = drv.Create("mem_1.mem", 50, 3) - ds = gdaltest.mem_ds + ds = drv.Create("mem_1.mem", 50, 3) assert ds.GetProjection() == "", "projection wrong" @@ -156,7 +139,14 @@ def test_mem_2(mem_native_memory): for i in range(width * height): float_p[i] = 5.0 - dsro = gdal.Open(dsname) + with pytest.raises( + Exception, + match="Opening a MEM dataset with the MEM:::DATAPOINTER= syntax is no longer supported by default for security reasons", + ): + gdal.Open(dsname) + + with gdal.config_option("GDAL_MEM_ENABLE_OPEN", "YES"): + dsro = gdal.Open(dsname) if dsro is None: free(p) pytest.fail("opening MEM dataset failed in read only mode.") @@ -168,7 +158,8 @@ def test_mem_2(mem_native_memory): pytest.fail("checksum failed.") dsro = None - dsup = gdal.Open(dsname, gdal.GA_Update) + with gdal.config_option("GDAL_MEM_ENABLE_OPEN", "YES"): + dsup = gdal.Open(dsname, gdal.GA_Update) if dsup is None: free(p) pytest.fail("opening MEM dataset failed in update mode.") @@ -210,9 +201,10 @@ def test_geotransform(ds_definition, expected_sr, mem_native_memory): proj_crs = "+proj=laea +lon_0=147 +lat_0=-42" ll_crs = """GEOGCS[\\"WGS 84\\",DATUM[\\"WGS_1984\\",SPHEROID[\\"WGS 84\\",6378137,298.257223563,AUTHORITY[\\"EPSG\\",\\"7030\\"]],AUTHORITY[\\"EPSG\\",\\"6326\\"]],PRIMEM[\\"Greenwich\\",0,AUTHORITY[\\"EPSG\\",\\"8901\\"]],UNIT[\\"degree\\",0.0174532925199433,AUTHORITY[\\"EPSG\\",\\"9122\\"]],AXIS[\\"Latitude\\",NORTH],AXIS[\\"Longitude\\",EAST],AUTHORITY[\\"EPSG\\",\\"4326\\"]]""" - dsro = gdal.Open( - ds_definition.format(datapointer=p, proj_crs=proj_crs, ll_crs=ll_crs) - ) + with gdal.config_option("GDAL_MEM_ENABLE_OPEN", "YES"): + dsro = gdal.Open( + ds_definition.format(datapointer=p, proj_crs=proj_crs, ll_crs=ll_crs) + ) if dsro is None: free(p) pytest.fail("opening MEM dataset failed in read only mode.") @@ -784,8 +776,16 @@ def test_mem_alpha_ismaskband(): ############################################################################### -# cleanup +# Check robustness to GDT_Unknown -def test_mem_cleanup(): - gdaltest.mem_ds = None +def test_mem_gdt_unknown(): + + with pytest.raises(Exception, match="Illegal GDT_Unknown/GDT_TypeCount argument"): + gdal.GetDriverByName("MEM").Create("", 1, 1, 1, gdal.GDT_Unknown) + + with gdal.GetDriverByName("MEM").Create("", 1, 1, 0, gdal.GDT_Unknown) as ds: + with pytest.raises( + Exception, match="Illegal GDT_Unknown/GDT_TypeCount argument" + ): + ds.AddBand(gdal.GDT_Unknown) diff --git a/autotest/gdrivers/memmultidim.py b/autotest/gdrivers/memmultidim.py index 0c59a4367536..a1b33c5a5ecc 100755 --- a/autotest/gdrivers/memmultidim.py +++ b/autotest/gdrivers/memmultidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -90,7 +74,7 @@ def test_mem_md_subgroup(): with gdal.quiet_errors(): assert not rg.CreateGroup("") # unnamed group not supported - with pytest.raises(ValueError): + with pytest.raises(Exception): assert not rg.CreateGroup(None) subg = rg.CreateGroup("subgroup") @@ -339,12 +323,12 @@ def test_mem_md_datatypes(): assert dt_byte.GetNumericDataType() == gdal.GDT_Byte assert dt_byte.GetSize() == 1 assert dt_byte.CanConvertTo(dt_byte) - with pytest.raises(ValueError): + with pytest.raises(Exception): assert dt_byte.CanConvertTo(None) assert dt_byte == gdal.ExtendedDataType.Create(gdal.GDT_Byte) assert not dt_byte != gdal.ExtendedDataType.Create(gdal.GDT_Byte) assert dt_byte.Equals(dt_byte) - with pytest.raises(ValueError): + with pytest.raises(Exception): assert dt_byte.Equals(None) assert not dt_byte.GetComponents() @@ -762,9 +746,9 @@ def test_mem_md_array_invalid_args(): rg.CreateMDArray("myarray", [None], edt) with pytest.raises((TypeError, SystemError)): rg.CreateMDArray("myarray", [1], edt) - with pytest.raises(ValueError): + with pytest.raises(Exception): rg.CreateMDArray("myarray", [dim], None) - with pytest.raises(ValueError): + with pytest.raises(Exception): rg.CreateMDArray(None, [dim], edt) @@ -837,7 +821,7 @@ def test_mem_md_group_attribute_single_numeric(): float64dt = gdal.ExtendedDataType.Create(gdal.GDT_Float64) with gdal.quiet_errors(): assert not rg.CreateAttribute("", [1], float64dt) # unnamed attr not supported - with pytest.raises(ValueError): + with pytest.raises(Exception): rg.CreateAttribute(None, [1], float64dt) attr = rg.CreateAttribute("attr", [1], float64dt) @@ -955,7 +939,7 @@ def test_mem_md_array_attribute(): assert not myarray.CreateAttribute( "", [1], float64dt ) # unnamed attr not supported - with pytest.raises(ValueError): + with pytest.raises(Exception): myarray.CreateAttribute(None, [1], float64dt) attr = myarray.CreateAttribute("attr", [1], float64dt) diff --git a/autotest/gdrivers/mff.py b/autotest/gdrivers/mff.py index 0cb2305c9851..f2db3f9d3daa 100755 --- a/autotest/gdrivers/mff.py +++ b/autotest/gdrivers/mff.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/mff2.py b/autotest/gdrivers/mff2.py index dcb5a85d4561..534cc844ee20 100755 --- a/autotest/gdrivers/mff2.py +++ b/autotest/gdrivers/mff2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/mrf.py b/autotest/gdrivers/mrf.py index c46f39bff99f..7cbe7b6376db 100755 --- a/autotest/gdrivers/mrf.py +++ b/autotest/gdrivers/mrf.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import glob @@ -203,6 +187,10 @@ def cleanup(base="/vsimem/out."): gdal.Unlink(base + ext) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_mrf_zen_test(): expectedCS = 770 diff --git a/autotest/gdrivers/mrsid.py b/autotest/gdrivers/mrsid.py index c84cd3f26d13..a1c887b31357 100755 --- a/autotest/gdrivers/mrsid.py +++ b/autotest/gdrivers/mrsid.py @@ -10,23 +10,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2009-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/ndf.py b/autotest/gdrivers/ndf.py index 708d9f0f38a0..e31bba57a01d 100755 --- a/autotest/gdrivers/ndf.py +++ b/autotest/gdrivers/ndf.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/netcdf.py b/autotest/gdrivers/netcdf.py index 56902f5367f1..6622974f49b4 100755 --- a/autotest/gdrivers/netcdf.py +++ b/autotest/gdrivers/netcdf.py @@ -12,23 +12,7 @@ # Copyright (c) 2008-2016, Even Rouault # Copyright (c) 2010, Kyle Shannon # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -562,7 +546,9 @@ def test_netcdf_11(): def test_netcdf_cf_geog_with_srs(): + gdal.ErrorReset() ds = gdal.Open("data/netcdf/cf_geog_with_srs.nc") + assert gdal.GetLastErrorMsg() == "" gt = ds.GetGeoTransform() assert gt == pytest.approx([-0.1, 0.2, 0, -79.1, 0, -0.2], rel=1e-5) @@ -1190,6 +1176,10 @@ def test_netcdf_28(tmp_path): # metadata to netcdf file with SetMetadata() and SetMetadataItem()). +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_netcdf_29(tmp_path): # create tif file using gdalwarp @@ -1451,6 +1441,10 @@ def test_netcdf_38(): # Test VRT and NETCDF: +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_netcdf_39(): shutil.copy("data/netcdf/two_vars_scale_offset.nc", "tmp") @@ -1482,6 +1476,10 @@ def test_netcdf_39(): assert cs == 65463 +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_netcdf_39_absolute(): if ( @@ -6546,7 +6544,7 @@ def test_netcdf_create_metadata_with_equal_sign(tmp_path): # Test force opening a HDF55 file with netCDF driver -def test_netcdf_force_opening_hdf5_file(tmp_vsimem): +def test_netcdf_force_opening_hdf5_file(): ds = gdal.OpenEx("data/hdf5/groups.h5", allowed_drivers=["netCDF"]) assert ds.GetDriver().GetDescription() == "netCDF" @@ -6563,3 +6561,58 @@ def test_netcdf_force_opening_no_match(): drv = gdal.IdentifyDriverEx("data/byte.tif", allowed_drivers=["netCDF"]) assert drv is None + + +############################################################################### + + +def test_netcdf_extra_dim_no_georef(tmp_path): + + fname = tmp_path / "out.nc" + + src_ds = gdal.Translate("", "../gcore/data/stefan_full_rgba.tif", format="MEM") + size_z = 4 + src_ds.SetMetadataItem("NETCDF_DIM_EXTRA", "{Z}") + src_ds.SetMetadataItem("NETCDF_DIM_Z_DEF", f"{{{size_z},4}}") + src_ds.SetMetadataItem("NETCDF_DIM_Z_VALUES", "{0,1,2,3}") + src_ds.SetMetadataItem("Z#axis", "Z") + + # Create netCDF file + gdal.GetDriverByName("netCDF").CreateCopy(fname, src_ds) + + ds = gdal.Open(fname) + assert ds.RasterCount == 4 + assert ds.ReadRaster() == src_ds.ReadRaster() + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. +# (might be risky depending on libopenjp2...) + + +@pytest.mark.parametrize( + "src_filename,golden_file,creation_options", + [ + # Created with gdal_translate gdal_translate autotest/gcore/data/byte.tif autotest/gdrivers/data/netcdf/byte_nc3_golden.nc -co WRITE_GDAL_VERSION=NO -co WRITE_GDAL_HISTORY=NO -co FORMAT=NC + ( + "../gcore/data/byte.tif", + "data/netcdf/byte_nc3_golden.nc", + ["WRITE_GDAL_VERSION=NO", "WRITE_GDAL_HISTORY=NO", "FORMAT=NC"], + ), + ], +) +# I've that feeling that netCDF might be host endianness dependent... +@pytest.mark.skipif( + sys.byteorder != "little", reason="only supported on little-endian hosts" +) +def test_netcdf_write_check_golden_file( + tmp_path, src_filename, golden_file, creation_options +): + + out_filename = str(tmp_path / "test.nc") + with gdal.Open(src_filename) as src_ds: + gdal.GetDriverByName("netCDF").CreateCopy( + out_filename, src_ds, options=creation_options + ) + assert os.stat(golden_file).st_size == os.stat(out_filename).st_size + assert open(golden_file, "rb").read() == open(out_filename, "rb").read() diff --git a/autotest/gdrivers/netcdf_cf.py b/autotest/gdrivers/netcdf_cf.py index 24edf4e53236..7e60718ed431 100755 --- a/autotest/gdrivers/netcdf_cf.py +++ b/autotest/gdrivers/netcdf_cf.py @@ -10,23 +10,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/netcdf_multidim.py b/autotest/gdrivers/netcdf_multidim.py index 46c347a42d99..253cb99b7197 100755 --- a/autotest/gdrivers/netcdf_multidim.py +++ b/autotest/gdrivers/netcdf_multidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -1528,6 +1512,10 @@ def copy(): gdal.Unlink(tmpfilename2) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_netcdf_multidim_dims_with_same_name_different_size(): src_ds = gdal.OpenEx( diff --git a/autotest/gdrivers/netcdf_multidim_pamproxydb.py b/autotest/gdrivers/netcdf_multidim_pamproxydb.py index 8091ff900d8e..f2884ab73c6d 100755 --- a/autotest/gdrivers/netcdf_multidim_pamproxydb.py +++ b/autotest/gdrivers/netcdf_multidim_pamproxydb.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/gdrivers/ngsgeoid.py b/autotest/gdrivers/ngsgeoid.py index 7c66f8b1a471..31cc41ef3b7f 100755 --- a/autotest/gdrivers/ngsgeoid.py +++ b/autotest/gdrivers/ngsgeoid.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/ngw.py b/autotest/gdrivers/ngw.py index 43befc3c9a92..71c3a8b76dd5 100755 --- a/autotest/gdrivers/ngw.py +++ b/autotest/gdrivers/ngw.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018-2021, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/nitf.py b/autotest/gdrivers/nitf.py index 9ca57a6a3634..0efaf689b8f4 100755 --- a/autotest/gdrivers/nitf.py +++ b/autotest/gdrivers/nitf.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -896,10 +880,11 @@ def test_nitf_28_jp2ecw(tmp_path): blockxsize, blockysize = ds.GetRasterBand(1).GetBlockSize() ds = None gdal.Unlink(tmpfilename) - assert (blockxsize, blockysize) == ( - 256, - 256, - ) # 256 since this is hardcoded as such in the ECW driver + # 256 for ECW < 5.1, 1024 for ECW >= 5.1 + assert (blockxsize, blockysize) == (256, 256) or (blockxsize, blockysize) == ( + 1024, + 1024, + ) finally: gdaltest.reregister_all_jpeg2000_drivers() @@ -986,9 +971,38 @@ def test_nitf_28_jp2openjpeg_bis(tmp_path): createcopy=True, ) ds = gdal.Open(filename) + size = os.stat(filename).st_size assert ds.GetRasterBand(1).Checksum() in (31604, 31741) ds = None + nitf_create( + filename, + ["ICORDS=G", "IC=C8", "QUALITY=1,25"], + set_inverted_color_interp=False, + createcopy=True, + ) + ds = gdal.Open(filename) + size2 = os.stat(filename).st_size + assert ds.GetRasterBand(1).Checksum() in (31604, 31741) + ds = None + + assert size2 > size + + # Check that floating-point values in QUALITY are honored + nitf_create( + filename, + ["ICORDS=G", "IC=C8", "QUALITY=1.9,25"], + set_inverted_color_interp=False, + createcopy=True, + ) + ds = gdal.Open(filename) + size3 = os.stat(filename).st_size + assert ds.GetRasterBand(1).Checksum() in (31604, 31741) + ds = None + + # The fact that size3 > size2 is a bit of a chance here... + assert size3 > size2 + tmpfilename = "/vsimem/nitf_28_jp2openjpeg_bis.ntf" src_ds = gdal.GetDriverByName("MEM").Create("", 1025, 1025) gdal.GetDriverByName("NITF").CreateCopy(tmpfilename, src_ds, options=["IC=C8"]) @@ -1100,6 +1114,7 @@ def test_nitf_jp2openjpeg_npje_numerically_lossless(tmp_vsimem): "IC=C8", "JPEG2000_DRIVER=JP2OpenJPEG", "PROFILE=NPJE_NUMERICALLY_LOSSLESS", + "QUALITY=10,100", ], ) @@ -1506,6 +1521,10 @@ def test_nitf_34(): # Test CreateCopy() writing file with a text segment. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_35(): src_ds = gdal.Open("data/nitf/text_md.vrt") @@ -1598,6 +1617,10 @@ def test_nitf_37(): # Create and read a NITF file with 999 images +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_38(): ds = gdal.Open("data/byte.tif") @@ -1978,6 +2001,10 @@ def test_nitf_check_jpeg2000_overviews(driver_to_test): # Check reading of rsets. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_47(): ds = gdal.Open("data/nitf/rset.ntf.r0") @@ -1997,6 +2024,10 @@ def test_nitf_47(): # Check building of standard overviews in place of rset overviews. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_48(): try: @@ -2038,6 +2069,10 @@ def test_nitf_48(): # Test TEXT and CGM creation options with CreateCopy() (#3376) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_49(): options = [ @@ -2759,6 +2794,10 @@ def test_nitf_68(): # Test SetGCPs() support +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_nitf_69(): vrt_txt = """ @@ -4079,6 +4118,386 @@ def test_nitf_86(): assert data == expected_data +############################################################################### +# Test parsing CSCSDB DES (STDI-0002-1-v5.0 App M) + + +def test_nitf_CSCSDB(tmp_vsimem): + tre_data = "DES=CSCSDB=01U 008517261ee9-2175-4ff2-86ad-dddda1f8270c001002001824ecf8e-1041-4cce-9edb-bc92d88624ca000020050407132420050407072409.88900000031231+2.50000000000000E+03+0.00000000000000E+00+0.00000000000000E+00+2.50000000000000E+03+0.00000000000000E+00+2.50000000000000E+0300101020050407072409.8890000002451+2.01640000000000E-08+0.00000000000000E+00+2.01640000000000E-080010312005040726649.889000000001.8750000000081+7.22500000000000E-09+0.00000000000000E+00+7.22500000000000E-09100104020050407072409.889000000161+2.01640000000000E-0800105020050407072409.889000000171+1.96000000000000E-0400107000100303+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+00+4.00000000000000E+00+0.00000000000000E+00+4.00000000000000E+000910107010101.0001.0000000.00000000.000000+1.00000000000000E+03020101.0001.0000000.00000000.000000+5.00000000000000E+02030101.0001.0000000.00000000.000000+5.00000000000000E+02040101.0001.0000000.00000000.000000+5.00000000000000E+02050101.0001.0000000.00000000.000000+5.00000000000000E+02060101.0001.0000000.00000000.000000+5.00000000000000E+02070101.0001.0000000.00000000.000000+1.00000000000000E+020000000000" + + filename = str(tmp_vsimem / "test.ntf") + ds = gdal.GetDriverByName("NITF").Create(filename, 1, 1, options=[tre_data]) + ds = None + + ds = gdal.Open(filename) + data = ds.GetMetadata("xml:DES")[0] + ds = None + + expected_data = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + assert data == expected_data + + ############################################################################### # Test parsing ILLUMB TRE (STDI-0002-1-v5.0 App AL) @@ -5316,7 +5735,8 @@ def test_nitf_invalid_udid(): def test_nitf_isubcat_populated(): # Check a dataset with IQ complex data. - ds = gdal.Open("data/nitf/sar_sicd.ntf") + with gdal.config_option("NITF_SAR_AS_COMPLEX_TYPE", "NO"): + ds = gdal.Open("data/nitf/sar_sicd.ntf") expected = ["I", "Q"] for b in range(ds.RasterCount): md = ds.GetRasterBand(b + 1).GetMetadata() @@ -5829,6 +6249,41 @@ def test_nitf_report_ABPP_as_NBITS(tmp_vsimem): assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "9" +############################################################################### +# Test reading SAR products with I,Q bands + + +def test_nitf_readSAR_IQ(tmp_vsimem): + + out_filename = str(tmp_vsimem / "tmp.ntf") + gdal.Translate( + out_filename, + "data/byte.tif", + options="-b 1 -b 1 -outsize 40 20 -co ICAT=SAR -ot Float32 -co ISUBCAT=I,Q -scale_2 0 255 255 0", + ) + gdal.Unlink(out_filename + ".aux.xml") + + ds = gdal.Open(out_filename) + assert ds.RasterCount == 1 + assert ds.RasterXSize == 40 + assert ds.RasterYSize == 20 + assert ds.GetRasterBand(1).DataType == gdal.GDT_CFloat32 + assert ds.GetMetadataItem("NITF_ISUBCAT") is None + + src_ds = gdal.Open("data/byte.tif") + ds = gdal.Open("DERIVED_SUBDATASET:REAL:" + out_filename) + assert ( + ds.ReadRaster(0, 0, 40, 20, 20, 20, buf_type=gdal.GDT_Byte) + == src_ds.ReadRaster() + ) + ds = gdal.Open("DERIVED_SUBDATASET:IMAG:" + out_filename) + mod_src_ds = gdal.Translate("", src_ds, options="-f MEM -scale 0 255 255 0") + assert ( + ds.ReadRaster(0, 0, 40, 20, 20, 20, buf_type=gdal.GDT_Byte) + == mod_src_ds.ReadRaster() + ) + + ############################################################################### # Test NITF21_CGM_ANNO_Uncompressed_unmasked.ntf for bug #1313 and #1714 diff --git a/autotest/gdrivers/noaa_b.py b/autotest/gdrivers/noaa_b.py index 9dda59e3981b..464bc69e3a41 100755 --- a/autotest/gdrivers/noaa_b.py +++ b/autotest/gdrivers/noaa_b.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/nsidcbin.py b/autotest/gdrivers/nsidcbin.py index 62a9192360b9..3818289f94be 100644 --- a/autotest/gdrivers/nsidcbin.py +++ b/autotest/gdrivers/nsidcbin.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, Michael Sumner, # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/ntv2.py b/autotest/gdrivers/ntv2.py index e0a119d3010f..fc98584b6d0a 100755 --- a/autotest/gdrivers/ntv2.py +++ b/autotest/gdrivers/ntv2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/nwt_grc.py b/autotest/gdrivers/nwt_grc.py index 36d2e1013274..72f9d2aeb8f5 100755 --- a/autotest/gdrivers/nwt_grc.py +++ b/autotest/gdrivers/nwt_grc.py @@ -9,27 +9,14 @@ ############################################################################### # Copyright (c) 2009, Chaitanya kumar CH, # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest +import pytest + +pytestmark = pytest.mark.require_driver("NWT_GRC") ############################################################################### # Test a GRC dataset diff --git a/autotest/gdrivers/nwt_grd.py b/autotest/gdrivers/nwt_grd.py index 04d8ca300946..40e3cafae287 100755 --- a/autotest/gdrivers/nwt_grd.py +++ b/autotest/gdrivers/nwt_grd.py @@ -9,31 +9,18 @@ ############################################################################### # Copyright (c) 2009, Chaitanya kumar CH, # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil import gdaltest +import pytest from osgeo import gdal +pytestmark = pytest.mark.require_driver("NWT_GRD") + ############################################################################### # Test a GRD dataset with three bands + Z @@ -51,6 +38,13 @@ def test_nwt_grd_1(): def test_nwt_grd_2(): + + if ( + gdal.GetDriverByName("NWT_GRD").GetMetadataItem(gdal.DMD_CREATIONDATATYPES) + is None + ): + pytest.skip("NWT_GRD driver has no write support due to missing MITAB driver") + """ Test writing a GRD via CreateCopy """ diff --git a/autotest/gdrivers/ogcapi.py b/autotest/gdrivers/ogcapi.py index fdebf3a42427..4edd36cbff41 100644 --- a/autotest/gdrivers/ogcapi.py +++ b/autotest/gdrivers/ogcapi.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, Alessandro Pasotti # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -211,6 +195,7 @@ def init(): @pytest.mark.parametrize("remove_type_application_json", [False, True]) +@pytest.mark.require_driver("OAPIF") def test_ogr_ogcapi_features(remove_type_application_json): global global_remove_type_application_json diff --git a/autotest/gdrivers/openfilegdb.py b/autotest/gdrivers/openfilegdb.py index 8afb9187e293..3ebc614b98d5 100755 --- a/autotest/gdrivers/openfilegdb.py +++ b/autotest/gdrivers/openfilegdb.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gdrivers/ozi.py b/autotest/gdrivers/ozi.py index 800b261a9011..59af83a14160 100755 --- a/autotest/gdrivers/ozi.py +++ b/autotest/gdrivers/ozi.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/paux.py b/autotest/gdrivers/paux.py index 7dc07d911cc4..4f9f62647ee9 100755 --- a/autotest/gdrivers/paux.py +++ b/autotest/gdrivers/paux.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2004, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/pcidsk.py b/autotest/gdrivers/pcidsk.py index d8c7f24b168c..37a5524e8214 100755 --- a/autotest/gdrivers/pcidsk.py +++ b/autotest/gdrivers/pcidsk.py @@ -11,23 +11,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2009-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -60,6 +44,7 @@ def test_pcidsk_1(): # Test lossless copying (16, multiband) via Create(). +@pytest.mark.require_driver("PNG") def test_pcidsk_2(): tst = gdaltest.GDALTest("PCIDSK", "png/rgba16.png", 2, 2042) @@ -222,6 +207,7 @@ def test_pcidsk_5(tmp_path): # Test FILE interleaving. +@pytest.mark.require_driver("PNG") def test_pcidsk_8(): tst = gdaltest.GDALTest( @@ -284,6 +270,7 @@ def test_pcidsk_10(): # Test INTERLEAVING=TILED interleaving. +@pytest.mark.require_driver("PNG") def test_pcidsk_11(): tst = gdaltest.GDALTest( @@ -297,6 +284,7 @@ def test_pcidsk_11(): tst.testCreate() +@pytest.mark.require_driver("PNG") def test_pcidsk_11_v1(): tst = gdaltest.GDALTest( @@ -310,6 +298,7 @@ def test_pcidsk_11_v1(): tst.testCreate() +@pytest.mark.require_driver("PNG") def test_pcidsk_11_v2(): tst = gdaltest.GDALTest( @@ -327,6 +316,7 @@ def test_pcidsk_11_v2(): # Test INTERLEAVING=TILED interleaving and COMPRESSION=RLE +@pytest.mark.require_driver("PNG") def test_pcidsk_12(): tst = gdaltest.GDALTest( @@ -340,6 +330,7 @@ def test_pcidsk_12(): tst.testCreate() +@pytest.mark.require_driver("PNG") def test_pcidsk_12_v1(): tst = gdaltest.GDALTest( @@ -358,6 +349,7 @@ def test_pcidsk_12_v1(): tst.testCreate() +@pytest.mark.require_driver("PNG") def test_pcidsk_12_v2(): tst = gdaltest.GDALTest( @@ -518,6 +510,8 @@ def test_pcidsk_external_ovr_rrd(): with gdaltest.config_option("USE_RRD", "YES"): ds.BuildOverviews("NEAR", [2]) ds = None + if gdal.GetLastErrorMsg() == "This build does not support creating .aux overviews": + pytest.skip(gdal.GetLastErrorMsg()) assert gdal.VSIStatL("/vsimem/test.aux") is not None ds = gdal.Open("/vsimem/test.pix") assert ds.GetRasterBand(1).GetOverviewCount() == 1 diff --git a/autotest/gdrivers/pcraster.py b/autotest/gdrivers/pcraster.py index d711c2d7db7d..753c36854648 100755 --- a/autotest/gdrivers/pcraster.py +++ b/autotest/gdrivers/pcraster.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2004, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/pdf.py b/autotest/gdrivers/pdf.py index 7db4786de764..7b74e9b5384c 100755 --- a/autotest/gdrivers/pdf.py +++ b/autotest/gdrivers/pdf.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -374,12 +358,14 @@ def test_pdf_ogcbp(poppler_or_pdfium_or_podofo): tst = gdaltest.GDALTest( "PDF", "byte.tif", 1, None, options=["GEO_ENCODING=OGC_BP"] ) + gdal.ErrorReset() tst.testCreateCopy( check_minmax=0, check_gt=1, check_srs=True, check_checksum_not_null=pdf_checksum_available(), ) + assert gdal.GetLastErrorMsg() == "" ############################################################################### @@ -1007,11 +993,19 @@ def _pdf_update_gcps(poppler_or_pdfium): gdaltest.pdf_drv.Delete(out_filename) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_update_gcps_iso32000(poppler_or_pdfium): gdal.SetConfigOption("GDAL_PDF_GEO_ENCODING", None) _pdf_update_gcps(poppler_or_pdfium) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_update_gcps_ogc_bp(poppler_or_pdfium): with gdal.config_option("GDAL_PDF_GEO_ENCODING", "OGC_BP"): _pdf_update_gcps(poppler_or_pdfium) @@ -1021,6 +1015,10 @@ def test_pdf_update_gcps_ogc_bp(poppler_or_pdfium): # Check SetGCPs() but with GCPs that do *not* resolve to a geotransform +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_set_5_gcps_ogc_bp(poppler_or_pdfium): dpi = 300 out_filename = "tmp/pdf_set_5_gcps_ogc_bp.pdf" @@ -1246,6 +1244,10 @@ def test_pdf_set_neatline_ogc_bp(poppler_or_pdfium): # Check that we can generate identical file +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_check_identity_iso32000(poppler_or_pdfium): out_filename = "tmp/pdf_check_identity_iso32000.pdf" @@ -1279,6 +1281,10 @@ def test_pdf_check_identity_iso32000(poppler_or_pdfium): # Check that we can generate identical file +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_check_identity_ogc_bp(poppler_or_pdfium): out_filename = "tmp/pdf_check_identity_ogc_bp.pdf" @@ -1453,6 +1459,10 @@ def test_pdf_custom_layout(poppler_or_pdfium): # Test CLIPPING_EXTENT, EXTRA_RASTERS, EXTRA_RASTERS_LAYER_NAME, OFF_LAYERS, EXCLUSIVE_LAYERS options +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_pdf_extra_rasters(poppler_or_pdfium): subbyte = """ PROJCS["NAD27 / UTM zone 11N",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.9786982139006,AUTHORITY["EPSG","7008"]],AUTHORITY["EPSG","6267"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4267"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","26711"]] @@ -1719,6 +1729,10 @@ def test_pdf_jpeg_direct_copy(poppler_or_pdfium): # Test direct copy of source JPEG file within VRT file +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("JPEG") def test_pdf_jpeg_in_vrt_direct_copy(poppler_or_pdfium): @@ -3331,3 +3345,14 @@ def test_pdf_iso32000_esri_as_epsg(): assert sr.GetAuthorityName(None) == "ESRI" assert sr.GetAuthorityCode(None) == "102422" assert gdal.GetLastErrorMsg() == "" + + +############################################################################### +# Test bugfix for https://issues.oss-fuzz.com/issues/376126833 + + +@pytest.mark.skipif(not have_read_support(), reason="no read support available") +def test_pdf_iso32000_invalid_srs(): + + # Just test that this does not crash + gdal.Open("data/pdf/invalid_srs.pdf") diff --git a/autotest/gdrivers/pds.py b/autotest/gdrivers/pds.py index e112c7d38a11..9bc9b5d40f37 100755 --- a/autotest/gdrivers/pds.py +++ b/autotest/gdrivers/pds.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/pds4.py b/autotest/gdrivers/pds4.py index 9439953e7790..dcf31e28ca28 100755 --- a/autotest/gdrivers/pds4.py +++ b/autotest/gdrivers/pds4.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017, Hobu Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import contextlib diff --git a/autotest/gdrivers/plmosaic.py b/autotest/gdrivers/plmosaic.py index 774bd6a9fbea..3c7edb225155 100755 --- a/autotest/gdrivers/plmosaic.py +++ b/autotest/gdrivers/plmosaic.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/gdrivers/png.py b/autotest/gdrivers/png.py index a80c76726f98..4136217e6e4f 100755 --- a/autotest/gdrivers/png.py +++ b/autotest/gdrivers/png.py @@ -10,23 +10,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/gdrivers/pnm.py b/autotest/gdrivers/pnm.py index 74aff3783bc1..c1119c8260bf 100755 --- a/autotest/gdrivers/pnm.py +++ b/autotest/gdrivers/pnm.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/postgisraster.py b/autotest/gdrivers/postgisraster.py index f00f9ce61954..ae8d53c2e244 100755 --- a/autotest/gdrivers/postgisraster.py +++ b/autotest/gdrivers/postgisraster.py @@ -12,23 +12,7 @@ # 2012, David Zwarg # Copyright (c) 2009-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/prf.py b/autotest/gdrivers/prf.py index 33e253f69879..310b60ba5257 100755 --- a/autotest/gdrivers/prf.py +++ b/autotest/gdrivers/prf.py @@ -5,23 +5,7 @@ ############################################################################### # Copyright (c) 2016, Andrew Sudorgin # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -85,6 +69,10 @@ def test_prf_3(): ds = None +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_prf_4(): tst = gdaltest.GDALTest("prf", "./PRF/dem.x-dem", 1, 0) diff --git a/autotest/gdrivers/r.py b/autotest/gdrivers/r.py index 3ead1e41c668..831872ab2784 100755 --- a/autotest/gdrivers/r.py +++ b/autotest/gdrivers/r.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/rasterlite.py b/autotest/gdrivers/rasterlite.py index 11ea371aefcc..c9083dd72a93 100755 --- a/autotest/gdrivers/rasterlite.py +++ b/autotest/gdrivers/rasterlite.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/rcm.py b/autotest/gdrivers/rcm.py new file mode 100755 index 000000000000..556e446bddbe --- /dev/null +++ b/autotest/gdrivers/rcm.py @@ -0,0 +1,140 @@ +#!/usr/bin/env pytest +############################################################################### +# $Id$ +# +# Project: GDAL/OGR Test Suite +# Purpose: Test RCM driver +# Author: Even Rouault, +# +############################################################################### +# Copyright (c) 2024, Even Rouault +# +# SPDX-License-Identifier: MIT +############################################################################### + + +import gdaltest +import pytest + +from osgeo import gdal + +pytestmark = pytest.mark.require_driver("RCM") + + +def test_rcm_open_from_root_dir(): + ds = gdal.Open("data/rcm/fake_VV_VH_GRD") + assert ds.GetDriver().ShortName == "RCM" + assert ds.RasterCount == 2 + + +def test_rcm_open_from_metadata_dir(): + ds = gdal.Open("data/rcm/fake_VV_VH_GRD/metadata") + assert ds.GetDriver().ShortName == "RCM" + assert ds.RasterCount == 2 + + +def test_rcm_open_from_product_xml(): + ds = gdal.Open("data/rcm/fake_VV_VH_GRD/metadata/product.xml") + assert ds.GetDriver().ShortName == "RCM" + assert ds.RasterCount == 2 + assert ds.RasterXSize == 17915 + assert ds.RasterYSize == 3297 + assert ds.GetRasterBand(1).DataType == gdal.GDT_UInt16 + assert ds.GetRasterBand(1).Checksum() == 0 + assert ds.GetRasterBand(1).GetMetadata() == {"POLARIMETRIC_INTERP": "VH"} + got_md = ds.GetMetadata() + new_got_md = {} + for k in got_md: + new_got_md[k] = got_md[k].replace("\\", "/") + assert new_got_md == { + "ACQUISITION_START_TIME": "rawDataStartTime", + "ACQUISITION_TYPE": "Medium Resolution 50m", + "BEAMS": "beams", + "BEAM_MODE": "Medium Resolution 50m", + "BEAM_MODE_DEFINITION_ID": "beamModeDefinitionId", + "BEAM_MODE_MNEMONIC": "beamModeMnemonic", + "BETA_NOUGHT_LUT": "data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VH.xml,data/rcm/fake_VV_VH_GRD/metadata/calibration/lutBeta_VV.xml", + "BITS_PER_SAMPLE": "16", + "DATA_TYPE": "Integer", + "FACILITY_IDENTIFIER": "inputDatasetFacilityId", + "FAR_RANGE_INCIDENCE_ANGLE": "incAngFarRng", + "FIRST_LINE_TIME": "zeroDopplerTimeFirstLine", + "GAMMA_LUT": "data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VH.xml,data/rcm/fake_VV_VH_GRD/metadata/calibration/lutGamma_VV.xml", + "GEODETIC_TERRAIN_HEIGHT": "200", + "LAST_LINE_TIME": "zeroDopplerTimeLastLine", + "LINE_SPACING": "sampledLineSpacing", + "LINE_TIME_ORDERING": "Increasing", + "LUT_APPLIED": "Mixed", + "NEAR_RANGE_INCIDENCE_ANGLE": "incAngNearRng", + "ORBIT_DATA_FILE": "orbitDataFileName", + "ORBIT_DATA_SOURCE": "Downlinked", + "ORBIT_DIRECTION": "Descending", + "PER_POLARIZATION_SCALING": "true", + "PIXEL_SPACING": "sampledPixelSpacing", + "PIXEL_TIME_ORDERING": "Decreasing", + "POLARIZATIONS": "VH VV", + "POLARIZATION_DATA_MODE": "Dual Co/Cross", + "PROCESSING_FACILITY": "processingFacility", + "PROCESSING_TIME": "processingTime", + "PRODUCT_ID": "productId", + "PRODUCT_TYPE": "GRD", + "SAMPLED_LINE_SPACING_TIME": "sampledLineSpacingTime", + "SAMPLED_PIXEL_SPACING_TIME": "sampledPixelSpacingTime", + "SAMPLE_TYPE": "Magnitude Detected", + "SATELLITE_HEIGHT": "600000", + "SATELLITE_IDENTIFIER": "RCM-1", + "SECURITY_CLASSIFICATION": "Non classifié / Unclassified", + "SENSOR_IDENTIFIER": "SAR", + "SIGMA_NOUGHT_LUT": "data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VH.xml,data/rcm/fake_VV_VH_GRD/metadata/calibration/lutSigma_VV.xml", + "SLANT_RANGE_FAR_EDGE": "slantRangeFarEdge", + "SLANT_RANGE_NEAR_EDGE": "slantRangeNearEdge", + } + assert ds.GetMetadata("RPC") == { + "ERR_BIAS": "0", + "ERR_RAND": "0", + "HEIGHT_OFF": "0", + "HEIGHT_SCALE": "0", + "LAT_OFF": "0", + "LAT_SCALE": "0", + "LINE_DEN_COEFF": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "LINE_NUM_COEFF": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "LINE_OFF": "0", + "LINE_SCALE": "0", + "LONG_OFF": "0", + "LONG_SCALE": "0", + "SAMP_DEN_COEFF": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "SAMP_NUM_COEFF": "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "SAMP_OFF": "0", + "SAMP_SCALE": "0", + } + assert ds.GetGCPSpatialRef().GetAuthorityCode(None) == "4326" + assert ds.GetGCPCount() == 1 + assert ds.GetGCPs()[0].GCPPixel == 2 + assert ds.GetGCPs()[0].GCPLine == 1 + assert ds.GetGCPs()[0].GCPX == 2.5 + assert ds.GetGCPs()[0].GCPY == 1.5 + assert ds.GetGCPs()[0].GCPZ == 3.5 + + +def test_rcm_open_subdatasets(): + + gdal.Open("RCM_CALIB:BETA0:data/rcm/fake_VV_VH_GRD/metadata/product.xml") + gdal.Open("RCM_CALIB:SIGMA0:data/rcm/fake_VV_VH_GRD/metadata/product.xml") + gdal.Open("RCM_CALIB:GAMMA:data/rcm/fake_VV_VH_GRD/metadata/product.xml") + gdal.Open("RCM_CALIB:UNCALIB:data/rcm/fake_VV_VH_GRD/metadata/product.xml") + with pytest.raises(Exception, match="Unsupported calibration type"): + gdal.Open("RCM_CALIB:unhandled:data/rcm/fake_VV_VH_GRD/metadata/product.xml") + with pytest.raises(Exception): + gdal.Open("RCM_CALIB:UNCALIB:i_do_not_exist/product.xml") + + +@pytest.mark.require_curl +def test_rcm_open_real_dataset(): + remote_file = "https://donnees-data.asc-csa.gc.ca/users/OpenData_DonneesOuvertes/pub/RCM/Antarctica/RCM3_OK2120467_PK2120468_3_SC30MCPB_20200124_083635_CH_CV_MLC/metadata/product.xml" + + if gdaltest.gdalurlopen(remote_file) is None: + pytest.skip(f"Could not read from {remote_file}") + + ds = gdal.Open("/vsicurl/" + remote_file) + assert ds.GetDriver().ShortName == "RCM" + assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32 diff --git a/autotest/gdrivers/rik.py b/autotest/gdrivers/rik.py index 35dcb113b392..4e6d00ce89cf 100755 --- a/autotest/gdrivers/rik.py +++ b/autotest/gdrivers/rik.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/rl2.py b/autotest/gdrivers/rl2.py index 9cf2f9cec6d2..b21743ee4036 100755 --- a/autotest/gdrivers/rl2.py +++ b/autotest/gdrivers/rl2.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/rmf.py b/autotest/gdrivers/rmf.py index 0b8fc5e52976..ac73d5a85dcb 100755 --- a/autotest/gdrivers/rmf.py +++ b/autotest/gdrivers/rmf.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Andrey Kiselev # Copyright (c) 2023, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/roipac.py b/autotest/gdrivers/roipac.py index 892a7c5769ac..29e5b925e60d 100755 --- a/autotest/gdrivers/roipac.py +++ b/autotest/gdrivers/roipac.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, Matthieu Volat # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/rpftoc.py b/autotest/gdrivers/rpftoc.py index 635e57d71eef..b77d085a33a0 100755 --- a/autotest/gdrivers/rpftoc.py +++ b/autotest/gdrivers/rpftoc.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/rraster.py b/autotest/gdrivers/rraster.py index c69638f06d85..87ecff82741e 100755 --- a/autotest/gdrivers/rraster.py +++ b/autotest/gdrivers/rraster.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pprint diff --git a/autotest/gdrivers/rs2.py b/autotest/gdrivers/rs2.py index fa42ea2eece1..fa034343d36f 100755 --- a/autotest/gdrivers/rs2.py +++ b/autotest/gdrivers/rs2.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -83,3 +67,15 @@ def test_rs2_3(): "SAMP_SCALE": "pixelScale", } assert got_rpc == expected_rpc + + +@pytest.mark.require_curl +def test_rs2_open_real_dataset(): + remote_file = "https://donnees-data.asc-csa.gc.ca/users/OpenData_DonneesOuvertes/pub/RADARSAT-2/RS2_OK103540_PK929658_DK864570_SLA12_20190317_110012_HH_SLC/product.xml" + + if gdaltest.gdalurlopen(remote_file) is None: + pytest.skip(f"Could not read from {remote_file}") + + ds = gdal.Open("/vsicurl/" + remote_file) + assert ds.GetDriver().ShortName == "RS2" + assert ds.GetRasterBand(1).DataType == gdal.GDT_CInt16 diff --git a/autotest/gdrivers/s102.py b/autotest/gdrivers/s102.py index 3e3010202319..171f40cfa44a 100755 --- a/autotest/gdrivers/s102.py +++ b/autotest/gdrivers/s102.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -211,34 +195,40 @@ def test_s102_multidim(): ############################################################################### -def test_s102_QualityOfSurvey(): +@pytest.mark.parametrize( + "filename,quality_group_name", + [ + ("data/s102/test_s102_v2.2_with_QualityOfSurvey.h5", "QualityOfSurvey"), + ( + "data/s102/test_s102_v3.0_with_QualityOfBathymetryCoverage.h5", + "QualityOfBathymetryCoverage", + ), + ], +) +def test_s102_QualityOfSurvey(filename, quality_group_name): - ds = gdal.Open("data/s102/test_s102_v2.2_with_QualityOfSurvey.h5") + ds = gdal.Open(filename) assert ds.GetSubDatasets() == [ ( - 'S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":BathymetryCoverage', + f'S102:"{filename}":BathymetryCoverage', "Bathymetric gridded data", ), ( - 'S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":QualityOfSurvey', - "Georeferenced metadata QualityOfSurvey", + f'S102:"{filename}":{quality_group_name}', + f"Georeferenced metadata {quality_group_name}", ), ] with pytest.raises(Exception, match="Unsupported subdataset component"): - gdal.Open('S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":invalid') + gdal.Open(f'S102:"{filename}":invalid') - ds = gdal.Open( - 'S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":BathymetryCoverage' - ) + ds = gdal.Open(f'S102:"{filename}":BathymetryCoverage') assert len(ds.GetSubDatasets()) == 0 assert ds.RasterCount == 2 assert ds.RasterXSize == 3 assert ds.RasterYSize == 2 - ds = gdal.Open( - 'S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":QualityOfSurvey' - ) + ds = gdal.Open(f'S102:"{filename}":{quality_group_name}') assert len(ds.GetSubDatasets()) == 0 assert ds.RasterCount == 1 assert ds.RasterXSize == 3 @@ -278,7 +268,7 @@ def test_s102_QualityOfSurvey(): assert rat.GetValueAsString(4, 2) == "e" ds = gdal.OpenEx( - 'S102:"data/s102/test_s102_v2.2_with_QualityOfSurvey.h5":QualityOfSurvey', + f'S102:"{filename}":{quality_group_name}', open_options=["NORTH_UP=NO"], ) assert ds.GetGeoTransform() == pytest.approx((1.8, 0.4, 0.0, 47.75, 0.0, 0.5)) diff --git a/autotest/gdrivers/s104.py b/autotest/gdrivers/s104.py index c9c2bb87c1b6..ca05884f2858 100755 --- a/autotest/gdrivers/s104.py +++ b/autotest/gdrivers/s104.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/s111.py b/autotest/gdrivers/s111.py index 2f45bacc9a2b..95d9e2dae3bd 100755 --- a/autotest/gdrivers/s111.py +++ b/autotest/gdrivers/s111.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/safe.py b/autotest/gdrivers/safe.py index d74a99f99f5b..df2656e19c30 100755 --- a/autotest/gdrivers/safe.py +++ b/autotest/gdrivers/safe.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -46,6 +30,12 @@ def test_safe_1(): tst = gdaltest.GDALTest("SAFE", "SAFE_FAKE/test.SAFE/manifest.safe", 1, 65372) tst.testOpen() + ds = gdal.Open("data/SAFE_FAKE/test.SAFE/manifest.safe") + assert ( + ds.GetMetadataItem("FOOTPRINT") + == "POLYGON((-8.407759 38.130520,-11.335915 38.535374,-11.026125 40.036644,-8.035001 39.633217, -8.407759 38.130520))" + ) + def test_safe_2(): diff --git a/autotest/gdrivers/saga.py b/autotest/gdrivers/saga.py index fbf21bf01df0..9e8811871d1f 100755 --- a/autotest/gdrivers/saga.py +++ b/autotest/gdrivers/saga.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/sar_ceos.py b/autotest/gdrivers/sar_ceos.py index 98656f16bbda..1f463ee77b72 100755 --- a/autotest/gdrivers/sar_ceos.py +++ b/autotest/gdrivers/sar_ceos.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/sdts.py b/autotest/gdrivers/sdts.py index b2714ffb504e..485613447c81 100755 --- a/autotest/gdrivers/sdts.py +++ b/autotest/gdrivers/sdts.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/sentinel2.py b/autotest/gdrivers/sentinel2.py index 63cbb9e6b836..e72ae4ba2d8c 100755 --- a/autotest/gdrivers/sentinel2.py +++ b/autotest/gdrivers/sentinel2.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -244,6 +228,9 @@ def test_sentinel2_l1c_2(): pprint.pprint(got_md) pytest.fail() + assert band.GetMetadataItem("CENTRAL_WAVELENGTH_UM", "IMAGERY") == "0.665" + assert band.GetMetadataItem("FWHM_UM", "IMAGERY") == "0.030" + assert band.GetColorInterpretation() == gdal.GCI_RedBand assert band.DataType == gdal.GDT_UInt16 @@ -252,7 +239,7 @@ def test_sentinel2_l1c_2(): band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -843,7 +830,7 @@ def test_sentinel2_l1c_tile_3(): band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -2618,7 +2605,7 @@ def test_sentinel2_l1c_safe_compact_2(): band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -2804,7 +2791,7 @@ def test_sentinel2_l1c_processing_baseline_5_09__1(): band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -2900,13 +2887,13 @@ def test_sentinel2_l1c_processing_baseline_5_09__2(): pprint.pprint(got_md) pytest.fail() - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_RedEdgeBand assert band.DataType == gdal.GDT_UInt16 band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -3035,7 +3022,7 @@ def test_sentinel2_l2a_processing_baseline_5_09__1(): band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { @@ -3158,13 +3145,13 @@ def test_sentinel2_l2a_processing_baseline_5_09__2(): pprint.pprint(got_md) pytest.fail() - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_RedEdgeBand assert band.DataType == gdal.GDT_UInt16 band = ds.GetRasterBand(4) - assert band.GetColorInterpretation() == gdal.GCI_Undefined + assert band.GetColorInterpretation() == gdal.GCI_NIRBand got_md = band.GetMetadata() expected_md = { diff --git a/autotest/gdrivers/sgi.py b/autotest/gdrivers/sgi.py index d1ef04845cdb..3ec03db2f091 100755 --- a/autotest/gdrivers/sgi.py +++ b/autotest/gdrivers/sgi.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/sigdem.py b/autotest/gdrivers/sigdem.py index 1670399e2c6c..d491eb7fcfbf 100755 --- a/autotest/gdrivers/sigdem.py +++ b/autotest/gdrivers/sigdem.py @@ -10,27 +10,12 @@ ############################################################################### # Copyright (c) 2018, Paul Austin # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest +import pytest ############################################################################### # Create simple copy and check. @@ -49,6 +34,10 @@ def test_sigdem_copy_check_prj(): # Verify writing files with non-square pixels. +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_sigdem_non_square(): tst = gdaltest.GDALTest("SIGDEM", "sigdem/nonsquare_nad27_utm11.vrt", 1, 12481) diff --git a/autotest/gdrivers/snap_tiff.py b/autotest/gdrivers/snap_tiff.py new file mode 100755 index 000000000000..e8e54455d12c --- /dev/null +++ b/autotest/gdrivers/snap_tiff.py @@ -0,0 +1,134 @@ +#!/usr/bin/env pytest +# -*- coding: utf-8 -*- +############################################################################### +# Project: GDAL/OGR Test Suite +# Purpose: SNAP_TIFF driver testing. +# Author: Even Rouault +# +############################################################################### +# Copyright (c) 2024, 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 pytest + +from osgeo import gdal + +pytestmark = pytest.mark.require_driver("SNAP_TIFF") + + +def test_snap_tiff(): + ds = gdal.Open( + "/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip" + ) + assert ds.GetDriver().GetDescription() == "SNAP_TIFF" + assert ds.RasterXSize == 25548 + assert ds.RasterYSize == 16716 + assert ds.RasterCount == 1 + assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32 + assert ds.GetGCPCount() == 4 + assert ds.GetGCPSpatialRef().GetAuthorityCode(None) == "4326" + gcps = ds.GetGCPs() + assert len(gcps) == 4 + assert gcps[0].GCPPixel == 0.5 + assert gcps[0].GCPLine == 0.5 + assert gcps[0].GCPX == -121.18662152623274 + assert gcps[0].GCPY == 39.655540466308594 + assert gcps[3].GCPPixel == 25547.5 + assert gcps[3].GCPLine == 16715.5 + assert gcps[3].GCPX == -124.43485147116212 + assert gcps[3].GCPY == 38.550738598352105 + assert ds.GetRasterBand(1).GetNoDataValue() == 0 + assert ds.GetRasterBand(1).GetDescription() == "Intensity_VV" + assert ds.GetRasterBand(1).GetUnitType() == "intensity" + assert ds.GetRasterBand(1).GetScale() == 1 + assert ds.GetRasterBand(1).GetOffset() == 0 + assert ds.GetMetadataDomainList() == [ + "", + "DERIVED_SUBDATASETS", + "GEOLOCATION", + "SUBDATASETS", + "xml:DIMAP", + ] + assert ds.GetMetadata() == { + "IMAGE_DESCRIPTION": "S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr" + } + assert ( + ds.GetMetadataItem("IMAGE_DESCRIPTION") + == "S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr" + ) + assert ds.GetMetadata("GEOLOCATION") == { + "LINE_OFFSET": "0", + "LINE_STEP": "16.025886864813039", + "PIXEL_OFFSET": "0", + "PIXEL_STEP": "16.02697616060226", + "SRS": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS ' + '84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]', + "X_BAND": "1", + "X_DATASET": 'SNAP_TIFF:"/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip":GEOLOCATION', + "Y_BAND": "2", + "Y_DATASET": 'SNAP_TIFF:"/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip":GEOLOCATION', + } + assert ds.GetMetadataItem("LINE_OFFSET", "GEOLOCATION") == "0" + assert ds.GetMetadata("SUBDATASETS") == { + "SUBDATASET_1_DESC": "Main content of " + "/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip", + "SUBDATASET_1_NAME": 'SNAP_TIFF:"/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip":MAIN', + "SUBDATASET_2_DESC": "Geolocation array of " + "/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip", + "SUBDATASET_2_NAME": 'SNAP_TIFF:"/vsizip/vsizip/data/snap_tiff/S1A_IW_GRDH_1SDV_20171009T141532_20171009T141557_018737_01F9E2_E974_tnr_empty_truncated.tif.zip.zip":GEOLOCATION', + } + assert ds.GetMetadata("xml:DIMAP")[0].startswith(" # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/srp.py b/autotest/gdrivers/srp.py index 1def42f714cd..bf186bb169d4 100755 --- a/autotest/gdrivers/srp.py +++ b/autotest/gdrivers/srp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/srtmhgt.py b/autotest/gdrivers/srtmhgt.py index 9ad1191de8a1..06eae960314c 100755 --- a/autotest/gdrivers/srtmhgt.py +++ b/autotest/gdrivers/srtmhgt.py @@ -10,23 +10,7 @@ # Copyright (c) 2005, Frank Warmerdam # Copyright (c) 2008-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gdrivers/stacit.py b/autotest/gdrivers/stacit.py index d08f8f8fda48..8c14463ae675 100755 --- a/autotest/gdrivers/stacit.py +++ b/autotest/gdrivers/stacit.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -162,7 +146,7 @@ def test_stacit_overlapping_sources(): # Check that the source covered by another one is not listed vrt = ds.GetMetadata("xml:VRT")[0] only_one_simple_source = """ - Gray + Coastal data/byte.tif 1 diff --git a/autotest/gdrivers/stacta.py b/autotest/gdrivers/stacta.py index 564cfc5fbd5d..7bce7f6e5054 100755 --- a/autotest/gdrivers/stacta.py +++ b/autotest/gdrivers/stacta.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import copy diff --git a/autotest/gdrivers/terragen.py b/autotest/gdrivers/terragen.py index c49ce7a91d97..dfb4eb9162a1 100755 --- a/autotest/gdrivers/terragen.py +++ b/autotest/gdrivers/terragen.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/test_validate_jp2.py b/autotest/gdrivers/test_validate_jp2.py index ad3d7e7c22cc..b652701feda7 100755 --- a/autotest/gdrivers/test_validate_jp2.py +++ b/autotest/gdrivers/test_validate_jp2.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, European Union (European Environment Agency) # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -114,6 +98,10 @@ def validate(filename, inspire_tg=True, expected_gmljp2=True, oidoc=None): # Highly corrupted file +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_validate_jp2_2(): import build_jp2_from_xml @@ -284,6 +272,10 @@ def test_validate_jp2_4(): # Also a RGN marker +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_validate_jp2_5(): import build_jp2_from_xml diff --git a/autotest/gdrivers/tga.py b/autotest/gdrivers/tga.py index ec841ca06c95..b09dfdd5f4e9 100644 --- a/autotest/gdrivers/tga.py +++ b/autotest/gdrivers/tga.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/gdrivers/til.py b/autotest/gdrivers/til.py index f1025e9519ab..8c7fe3b2407b 100755 --- a/autotest/gdrivers/til.py +++ b/autotest/gdrivers/til.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/tiledb_multidim.py b/autotest/gdrivers/tiledb_multidim.py index 7b3b87f7da1c..738ad873d0a9 100755 --- a/autotest/gdrivers/tiledb_multidim.py +++ b/autotest/gdrivers/tiledb_multidim.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, TileDB, Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/gdrivers/tiledb_read.py b/autotest/gdrivers/tiledb_read.py index 2f4607830304..13f11e010777 100755 --- a/autotest/gdrivers/tiledb_read.py +++ b/autotest/gdrivers/tiledb_read.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2019, TileDB, Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/tiledb_write.py b/autotest/gdrivers/tiledb_write.py index 8fc07d0e5f6f..31107fd4b0c8 100755 --- a/autotest/gdrivers/tiledb_write.py +++ b/autotest/gdrivers/tiledb_write.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2019, TileDB, Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math diff --git a/autotest/gdrivers/usgsdem.py b/autotest/gdrivers/usgsdem.py index 554c4e12d978..72737b7b5852 100755 --- a/autotest/gdrivers/usgsdem.py +++ b/autotest/gdrivers/usgsdem.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/vicar.py b/autotest/gdrivers/vicar.py index 4b37ad125d75..0ed10e2d1ad8 100755 --- a/autotest/gdrivers/vicar.py +++ b/autotest/gdrivers/vicar.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/gdrivers/vrtderived.py b/autotest/gdrivers/vrtderived.py index b5fd42965881..a5b5a39368ac 100755 --- a/autotest/gdrivers/vrtderived.py +++ b/autotest/gdrivers/vrtderived.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011, Antonio Valentino # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -37,6 +21,10 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) ############################################################################### @pytest.fixture(autouse=True, scope="module") diff --git a/autotest/gdrivers/vrtfilt.py b/autotest/gdrivers/vrtfilt.py index 579a4003509f..fa1d9879936d 100755 --- a/autotest/gdrivers/vrtfilt.py +++ b/autotest/gdrivers/vrtfilt.py @@ -10,23 +10,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -34,6 +18,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Verify simple 3x3 averaging filter. diff --git a/autotest/gdrivers/vrtlut.py b/autotest/gdrivers/vrtlut.py index 251e89ae21ff..ce7f80fed916 100755 --- a/autotest/gdrivers/vrtlut.py +++ b/autotest/gdrivers/vrtlut.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct @@ -35,6 +19,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Simple test diff --git a/autotest/gdrivers/vrtmask.py b/autotest/gdrivers/vrtmask.py index 13b3822176d9..3a5b7cfc8101 100755 --- a/autotest/gdrivers/vrtmask.py +++ b/autotest/gdrivers/vrtmask.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -36,6 +20,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Test with a global dataset mask band diff --git a/autotest/gdrivers/vrtmultidim.py b/autotest/gdrivers/vrtmultidim.py index 1c701a6b0b54..b05271c1b18f 100755 --- a/autotest/gdrivers/vrtmultidim.py +++ b/autotest/gdrivers/vrtmultidim.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -36,6 +20,10 @@ from osgeo import gdal, osr +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) ############################################################################### @pytest.fixture(autouse=True, scope="module") diff --git a/autotest/gdrivers/vrtovr.py b/autotest/gdrivers/vrtovr.py index da56dc867369..89382fd65bf7 100755 --- a/autotest/gdrivers/vrtovr.py +++ b/autotest/gdrivers/vrtovr.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct @@ -35,6 +19,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Simple test diff --git a/autotest/gdrivers/vrtpansharpen.py b/autotest/gdrivers/vrtpansharpen.py index e3ba9af028d4..6df41becf6c4 100755 --- a/autotest/gdrivers/vrtpansharpen.py +++ b/autotest/gdrivers/vrtpansharpen.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil @@ -36,6 +20,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + @pytest.fixture(autouse=True, scope="module") def startup_and_cleanup(): diff --git a/autotest/gdrivers/vrtprocesseddataset.py b/autotest/gdrivers/vrtprocesseddataset.py index b11483b16df0..eea8907b0ced 100755 --- a/autotest/gdrivers/vrtprocesseddataset.py +++ b/autotest/gdrivers/vrtprocesseddataset.py @@ -7,23 +7,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -31,6 +15,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + np = pytest.importorskip("numpy") pytest.importorskip("osgeo.gdal_array") @@ -719,6 +708,58 @@ def test_vrtprocesseddataset_dehazing_different_resolution(tmp_vsimem): ) +############################################################################### +# Test we properly request auxiliary datasets on the right-most/bottom-most +# truncated tile + + +def test_vrtprocesseddataset_dehazing_edge_effects(tmp_vsimem): + + src_filename = str(tmp_vsimem / "src.tif") + src_ds = gdal.GetDriverByName("GTiff").Create( + src_filename, + 257, + 257, + 1, + gdal.GDT_Byte, + ["TILED=YES", "BLOCKXSIZE=256", "BLOCKYSIZE=256"], + ) + src_ds.GetRasterBand(1).Fill(10) + src_ds.SetGeoTransform([0, 1, 0, 0, 0, -1]) + src_ds.Close() + + gain_filename = str(tmp_vsimem / "gain.tif") + gain_ds = gdal.GetDriverByName("GTiff").Create(gain_filename, 1, 1) + gain_ds.GetRasterBand(1).Fill(2) + gain_ds.SetGeoTransform([0, 257, 0, 0, 0, -257]) + gain_ds.Close() + + offset_filename = str(tmp_vsimem / "offset.tif") + offset_ds = gdal.GetDriverByName("GTiff").Create(offset_filename, 1, 1) + offset_ds.GetRasterBand(1).Fill(3) + offset_ds.SetGeoTransform([0, 257, 0, 0, 0, -257]) + offset_ds.Close() + + ds = gdal.Open( + f""" + + {src_filename} + + + + LocalScaleOffset + {gain_filename} + 1 + {offset_filename} + 1 + + + + """ + ) + assert ds.GetRasterBand(1).ComputeRasterMinMax() == (17, 17) + + ############################################################################### # Test error cases of LocalScaleOffset algorithm diff --git a/autotest/gdrivers/vrtrawlink.py b/autotest/gdrivers/vrtrawlink.py index 1f4203fc2874..a8d1d226b05f 100755 --- a/autotest/gdrivers/vrtrawlink.py +++ b/autotest/gdrivers/vrtrawlink.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -37,6 +21,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + def _xmlsearch(root, nodetype, name): for node in root[2:]: diff --git a/autotest/gdrivers/vrtwarp.py b/autotest/gdrivers/vrtwarp.py index 9b843aa81342..5532084e1fbd 100755 --- a/autotest/gdrivers/vrtwarp.py +++ b/autotest/gdrivers/vrtwarp.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2004, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -38,6 +22,11 @@ from osgeo import gdal +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + ############################################################################### # Verify reading from simple existing warp definition. @@ -100,6 +89,12 @@ def test_vrtwarp_4(): tmp_ds.BuildOverviews("NONE", overviewlist=[2, 4]) tmp_ds.GetRasterBand(1).GetOverview(0).Fill(127) cs_ov0 = tmp_ds.GetRasterBand(1).GetOverview(0).Checksum() + data_ov0 = tmp_ds.GetRasterBand(1).GetOverview(0).ReadRaster() + data_ov0_subsampled = ( + tmp_ds.GetRasterBand(1) + .GetOverview(0) + .ReadRaster(0, 0, 10, 10, 9, 9, resample_alg=gdal.GRIORA_Bilinear) + ) tmp_ds.GetRasterBand(1).GetOverview(1).Fill(255) cs_ov1 = tmp_ds.GetRasterBand(1).GetOverview(1).Checksum() @@ -109,6 +104,8 @@ def test_vrtwarp_4(): for i in range(3): assert vrtwarp_ds.GetRasterBand(1).GetOverviewCount() == 2 assert vrtwarp_ds.GetRasterBand(1).Checksum() == cs_main, i + assert vrtwarp_ds.GetRasterBand(1).GetOverview(-1) is None + assert vrtwarp_ds.GetRasterBand(1).GetOverview(2) is None assert vrtwarp_ds.GetRasterBand(1).GetOverview(0).Checksum() == cs_ov0 assert vrtwarp_ds.GetRasterBand(1).GetOverview(1).Checksum() == cs_ov1 if i == 0: @@ -136,6 +133,13 @@ def test_vrtwarp_4(): assert vrtwarp_ds.GetRasterBand(1).GetOverviewCount() == 3 assert vrtwarp_ds.GetRasterBand(1).Checksum() == cs_main assert vrtwarp_ds.GetRasterBand(1).GetOverview(0).Checksum() == cs_ov0 + assert vrtwarp_ds.GetRasterBand(1).ReadRaster(0, 0, 20, 20, 10, 10) == data_ov0 + assert ( + vrtwarp_ds.GetRasterBand(1).ReadRaster( + 0, 0, 20, 20, 9, 9, resample_alg=gdal.GRIORA_Bilinear + ) + == data_ov0_subsampled + ) assert vrtwarp_ds.GetRasterBand(1).GetOverview(1).Checksum() == cs_ov1 assert vrtwarp_ds.GetRasterBand(1).GetOverview(2).Checksum() == expected_cs_ov2 vrtwarp_ds = None @@ -714,8 +718,15 @@ def test_vrtwarp_irasterio_optim_three_band(): assert warped_vrt_ds.ReadRaster(buf_type=gdal.GDT_UInt16) == expected_data with gdaltest.config_option("GDAL_VRT_WARP_USE_DATASET_RASTERIO", "NO"): - expected_data = warped_vrt_ds.ReadRaster(buf_xsize=20, buf_ysize=20) - assert warped_vrt_ds.ReadRaster(buf_xsize=20, buf_ysize=20) == expected_data + expected_data = warped_vrt_ds.ReadRaster(buf_xsize=20, buf_ysize=40) + assert warped_vrt_ds.ReadRaster(buf_xsize=20, buf_ysize=40) == expected_data + + with gdaltest.config_option("GDAL_VRT_WARP_USE_DATASET_RASTERIO", "NO"): + expected_data = warped_vrt_ds.ReadRaster(1, 2, 3, 4, buf_xsize=20, buf_ysize=40) + assert ( + warped_vrt_ds.ReadRaster(1, 2, 3, 4, buf_xsize=20, buf_ysize=40) + == expected_data + ) ############################################################################### @@ -760,3 +771,15 @@ def test_vrtwarp_autocreatewarpedvrt_invalid_nodata(): ds.GetRasterBand(1).SetNoDataValue(-9999) vrt_ds = gdal.AutoCreateWarpedVRT(ds) assert vrt_ds.GetRasterBand(1).DataType == gdal.GDT_Byte + + +############################################################################### + + +def test_vrtwarp_add_band_gdt_unknown(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 1, gdal.GDT_Byte) + ds.SetGeoTransform([0, 1, 0, 0, 0, -1]) + vrt_ds = gdal.AutoCreateWarpedVRT(ds) + with pytest.raises(Exception, match="Illegal GDT_Unknown/GDT_TypeCount argument"): + vrt_ds.AddBand(gdal.GDT_Unknown) diff --git a/autotest/gdrivers/wcs.py b/autotest/gdrivers/wcs.py index 514f2508a785..aff6ea11e8d1 100755 --- a/autotest/gdrivers/wcs.py +++ b/autotest/gdrivers/wcs.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/gdrivers/webp.py b/autotest/gdrivers/webp.py index 0f2d56f8dfbd..1e67cca72500 100755 --- a/autotest/gdrivers/webp.py +++ b/autotest/gdrivers/webp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/wms.py b/autotest/gdrivers/wms.py index 9e7ca4da5508..dee274fdabd6 100755 --- a/autotest/gdrivers/wms.py +++ b/autotest/gdrivers/wms.py @@ -11,23 +11,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2007-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import base64 @@ -568,6 +552,10 @@ def test_wms_12(): # Test reading WMS through VRT (test effect of r21866) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @gdaltest.disable_exceptions() def test_wms_13(): diff --git a/autotest/gdrivers/wmts.py b/autotest/gdrivers/wmts.py index 93e117939475..f0e7b985157b 100755 --- a/autotest/gdrivers/wmts.py +++ b/autotest/gdrivers/wmts.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil @@ -880,6 +864,7 @@ def test_wmts_15(): + """, ) diff --git a/autotest/gdrivers/xmp.py b/autotest/gdrivers/xmp.py index 44d16432b802..4196f201209b 100755 --- a/autotest/gdrivers/xmp.py +++ b/autotest/gdrivers/xmp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/gdrivers/xpm.py b/autotest/gdrivers/xpm.py index 06f05a165bf5..514b28dd09db 100755 --- a/autotest/gdrivers/xpm.py +++ b/autotest/gdrivers/xpm.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/gdrivers/xyz.py b/autotest/gdrivers/xyz.py index 9914bfa38602..ac63ff4284fe 100755 --- a/autotest/gdrivers/xyz.py +++ b/autotest/gdrivers/xyz.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/gdrivers/zarr_driver.py b/autotest/gdrivers/zarr_driver.py index 3056cd1b0ce7..7d118e00c4d0 100644 --- a/autotest/gdrivers/zarr_driver.py +++ b/autotest/gdrivers/zarr_driver.py @@ -9,29 +9,14 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array import base64 import json import math +import os import struct import sys @@ -5539,3 +5524,63 @@ def test_zarr_read_cf1_zarrv3(): ds.GetSpatialRef().ExportToProj4() == "+proj=utm +zone=11 +ellps=clrk66 +units=m +no_defs" ) + + +############################################################################### +# Test bug fix for https://github.com/OSGeo/gdal/issues/11016 + + +@gdaltest.enable_exceptions() +def test_zarr_write_partial_blocks_compressed(tmp_vsimem): + + out_filename = str(tmp_vsimem / "test.zarr") + src_ds = gdal.Open("data/small_world.tif") + gdal.Translate( + out_filename, + src_ds, + options="-of ZARR -co FORMAT=ZARR_V2 -co BLOCKSIZE=3,50,50 -co COMPRESS=ZLIB -co INTERLEAVE=BAND", + ) + out_ds = gdal.Open(out_filename) + assert out_ds.ReadRaster() == src_ds.ReadRaster() + + +############################################################################### +# Test bug fix for https://github.com/OSGeo/gdal/issues/11023 + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize("format", ["ZARR_V2", "ZARR_V3"]) +def test_zarr_write_cleanup_create_dir_if_bad_blocksize(tmp_path, format): + + out_dirname = str(tmp_path / "test.zarr") + with pytest.raises(Exception): + gdal.Translate( + out_dirname, + "data/byte.tif", + options=f"-of ZARR -co FORMAT={format} -co BLOCKSIZE=1,20,20", + ) + assert not os.path.exists(out_dirname) + + +############################################################################### +# Test bug fix for https://github.com/OSGeo/gdal/issues/11023 + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize("format", ["ZARR_V2", "ZARR_V3"]) +def test_zarr_write_cleanup_create_dir_if_bad_blocksize_append_subdataset( + tmp_path, format +): + + out_dirname = str(tmp_path / "test.zarr") + gdal.Translate(out_dirname, "data/byte.tif", format="ZARR") + assert os.path.exists(out_dirname) + with pytest.raises(Exception): + gdal.Translate( + out_dirname, + "data/utm.tif", + options=f"-of ZARR -co APPEND_SUBDATASET=YES -co FORMAT={format} -co ARRAY_NAME=other -co BLOCKSIZE=1,20,20", + ) + assert os.path.exists(out_dirname) + ds = gdal.Open(out_dirname) + assert ds.GetRasterBand(1).Checksum() == 4672 diff --git a/autotest/gdrivers/zmap.py b/autotest/gdrivers/zmap.py index e7d62f876cf8..8edf855053bc 100755 --- a/autotest/gdrivers/zmap.py +++ b/autotest/gdrivers/zmap.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/generate_parquet_test_file.py b/autotest/generate_parquet_test_file.py index 71e226d4ed9e..3f8b723de818 100644 --- a/autotest/generate_parquet_test_file.py +++ b/autotest/generate_parquet_test_file.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### wkt_epsg_4326 = ( @@ -1245,6 +1229,91 @@ def __arrow_ext_deserialize__(cls, storage_type, serialized): ) +def generate_arrow_stringview(): + import pathlib + + import pyarrow as pa + import pyarrow.feather as feather + + stringview = pa.array(["foo", "bar", "looooooooooong string"], pa.string_view()) + list_stringview = pa.array( + [None, [None], ["foo", "bar", "looooooooooong string"]], + pa.list_(pa.string_view()), + ) + list_of_list_stringview = pa.array( + [None, [None], [["foo", "bar", "looooooooooong string"]]], + pa.list_(pa.list_(pa.string_view())), + ) + map_stringview = pa.array( + [None, [], [("x", "x_val"), ("y", None)]], + type=pa.map_(pa.string_view(), pa.string_view()), + ) + + names = [ + "stringview", + "list_stringview", + "list_of_list_stringview", + "map_stringview", + ] + + locals_ = locals() + table = pa.table([locals_[x] for x in names], names=names) + + HERE = pathlib.Path(__file__).parent + feather.write_feather(table, HERE / "ogr/data/arrow/stringview.feather") + + +def generate_arrow_binaryview(): + import pathlib + + import pyarrow as pa + import pyarrow.feather as feather + + binaryview = pa.array([b"foo", b"bar", b"looooooooooong binary"], pa.binary_view()) + + names = ["binaryview"] + + locals_ = locals() + table = pa.table([locals_[x] for x in names], names=names) + + HERE = pathlib.Path(__file__).parent + feather.write_feather(table, HERE / "ogr/data/arrow/binaryview.feather") + + +def generate_arrow_listview(): + import pathlib + + import pyarrow as pa + import pyarrow.feather as feather + + listview = pa.array([[1]], pa.list_view(pa.int32())) + + names = ["listview"] + + locals_ = locals() + table = pa.table([locals_[x] for x in names], names=names) + + HERE = pathlib.Path(__file__).parent + feather.write_feather(table, HERE / "ogr/data/arrow/listview.feather") + + +def generate_arrow_largelistview(): + import pathlib + + import pyarrow as pa + import pyarrow.feather as feather + + largelistview = pa.array([[1]], pa.large_list_view(pa.int32())) + + names = ["largelistview"] + + locals_ = locals() + table = pa.table([locals_[x] for x in names], names=names) + + HERE = pathlib.Path(__file__).parent + feather.write_feather(table, HERE / "ogr/data/arrow/largelistview.feather") + + if __name__ == "__main__": generate_test_parquet() generate_all_geoms_parquet() @@ -1252,3 +1321,7 @@ def __arrow_ext_deserialize__(cls, storage_type, serialized): generate_nested_types() generate_extension_custom() generate_extension_json() + generate_arrow_stringview() + generate_arrow_binaryview() + generate_arrow_listview() + generate_arrow_largelistview() diff --git a/autotest/gnm/gnm_test.py b/autotest/gnm/gnm_test.py index f42e6610415b..f82cbaf71270 100755 --- a/autotest/gnm/gnm_test.py +++ b/autotest/gnm/gnm_test.py @@ -12,23 +12,7 @@ # Copyright (c) 2014, Mikhail Gusev # Copyright (c) 2014-2015, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -52,7 +36,7 @@ def test_gnm_filenetwork_create(): pass drv = gdal.GetDriverByName("GNMFile") - ds = drv.Create( + with drv.Create( "tmp/", 0, 0, @@ -63,17 +47,15 @@ def test_gnm_filenetwork_create(): "net_description=Test file based GNM", "net_srs=EPSG:4326", ], - ) - # cast to GNM - dn = gnm.CastToNetwork(ds) - assert dn is not None - assert dn.GetVersion() == 100, "GNM: Check GNM version failed" - assert dn.GetName() == "test_gnm", "GNM: Check GNM name failed" - assert ( - dn.GetDescription() == "Test file based GNM" - ), "GNM: Check GNM description failed" - - dn = None + ) as ds: + # cast to GNM + dn = gnm.CastToNetwork(ds) + assert dn is not None + assert dn.GetVersion() == 100, "GNM: Check GNM version failed" + assert dn.GetName() == "test_gnm", "GNM: Check GNM name failed" + assert ( + dn.GetDescription() == "Test file based GNM" + ), "GNM: Check GNM description failed" ############################################################################### diff --git a/autotest/ogc_cite_testing/generate_sample_gpkg.py b/autotest/ogc_cite_testing/generate_sample_gpkg.py index 98735a0aa759..420445049b1d 100755 --- a/autotest/ogc_cite_testing/generate_sample_gpkg.py +++ b/autotest/ogc_cite_testing/generate_sample_gpkg.py @@ -7,23 +7,7 @@ ############################################################################### # Copyright (c) 2014-2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/ogc_cite_testing/kml_generate_test_files.py b/autotest/ogc_cite_testing/kml_generate_test_files.py index 3aff01641804..f18ee7c6f9ca 100755 --- a/autotest/ogc_cite_testing/kml_generate_test_files.py +++ b/autotest/ogc_cite_testing/kml_generate_test_files.py @@ -12,23 +12,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### from osgeo import gdal, ogr diff --git a/autotest/ogr/data/arrow/binaryview.feather b/autotest/ogr/data/arrow/binaryview.feather new file mode 100644 index 000000000000..9f62bd82944c Binary files /dev/null and b/autotest/ogr/data/arrow/binaryview.feather differ diff --git a/autotest/ogr/data/arrow/largelistview.feather b/autotest/ogr/data/arrow/largelistview.feather new file mode 100644 index 000000000000..65e2ffc575e1 Binary files /dev/null and b/autotest/ogr/data/arrow/largelistview.feather differ diff --git a/autotest/ogr/data/arrow/listview.feather b/autotest/ogr/data/arrow/listview.feather new file mode 100644 index 000000000000..c9737dff6168 Binary files /dev/null and b/autotest/ogr/data/arrow/listview.feather differ diff --git a/autotest/ogr/data/arrow/stringview.feather b/autotest/ogr/data/arrow/stringview.feather new file mode 100644 index 000000000000..43ab1534e0f8 Binary files /dev/null and b/autotest/ogr/data/arrow/stringview.feather differ diff --git a/autotest/ogr/data/duckdb/poly.duckdb b/autotest/ogr/data/duckdb/poly.duckdb new file mode 100644 index 000000000000..71322dc9c328 Binary files /dev/null and b/autotest/ogr/data/duckdb/poly.duckdb differ diff --git a/autotest/ogr/data/gml/billionlaugh.gml b/autotest/ogr/data/gml/billionlaugh.gml new file mode 100644 index 000000000000..6fc911bf771f --- /dev/null +++ b/autotest/ogr/data/gml/billionlaugh.gml @@ -0,0 +1,21 @@ + + + + + + + + + + + +]> + + &lol9; + diff --git a/autotest/ogr/data/gml/billionlaugh.xsd b/autotest/ogr/data/gml/billionlaugh.xsd new file mode 100644 index 000000000000..1e8c85b3fa03 --- /dev/null +++ b/autotest/ogr/data/gml/billionlaugh.xsd @@ -0,0 +1,69 @@ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autotest/ogr/data/gpkg/poly_golden.gpkg b/autotest/ogr/data/gpkg/poly_golden.gpkg new file mode 100644 index 000000000000..ab45c9747eee Binary files /dev/null and b/autotest/ogr/data/gpkg/poly_golden.gpkg differ diff --git a/autotest/ogr/data/miramon_inputs/LT05_L2SP_038037_20120505_20200820_02_T1_ST_stac_minimal.json b/autotest/ogr/data/miramon_inputs/LT05_L2SP_038037_20120505_20200820_02_T1_ST_stac_minimal.json new file mode 100644 index 000000000000..adb517d9a5a0 --- /dev/null +++ b/autotest/ogr/data/miramon_inputs/LT05_L2SP_038037_20120505_20200820_02_T1_ST_stac_minimal.json @@ -0,0 +1,72 @@ +{ + "type": "Feature", + "stac_version": "1.0.0", + "stac_extensions": [ + "https://landsat.usgs.gov/stac/landsat-extension/v1.1.1/schema.json", + "https://stac-extensions.github.io/view/v1.0.0/schema.json", + "https://stac-extensions.github.io/projection/v1.0.0/schema.json", + "https://stac-extensions.github.io/file/v1.0.0/schema.json", + "https://stac-extensions.github.io/eo/v1.0.0/schema.json", + "https://stac-extensions.github.io/alternate-assets/v1.1.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json" + ], + "id": "LT05_L2SP_038037_20120505_20200820_02_T1_ST", + "description": "Landsat Collection 2 Level-2 Surface Temperature Product", + "bbox": [ + -115.36191290268081, + 32.24471141532095, + -112.88724647545278, + 34.131291778950825 + ], + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -114.94540659929078, + 34.131291778950825 + ], + [ + -115.36191290268081, + 32.54075651753658 + ], + [ + -113.33774064709293, + 32.24471141532095 + ], + [ + -112.88724647545278, + 33.830888258627866 + ], + [ + -114.94540659929078, + 34.131291778950825 + ] + ] + ] + }, + "properties": { + "datetime": "2012-05-05T17:54:06.781038Z", + "eo:cloud_cover": 3.0, + "view:sun_azimuth": 120.71516953, + "view:sun_elevation": 62.1424525, + "platform": "LANDSAT_5", + "instruments": [ + "TM" + ], + "landsat:correction": "L2SP", + "proj:epsg": 32611, + "proj:shape": [ + 6951, + 7851 + ], + "proj:transform": [ + 30.0, + 0.0, + 649485.0, + 0.0, + -30.0, + 3780015.0 + ] + }, +} \ No newline at end of file diff --git a/autotest/ogr/data/nas/billionlaugh.xml b/autotest/ogr/data/nas/billionlaugh.xml new file mode 100644 index 000000000000..24f73f6e6614 --- /dev/null +++ b/autotest/ogr/data/nas/billionlaugh.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + +]> + + + &lol9; + <?xml version="1.0" encoding="utf-8"?><Protocol xmlns="http://www.aed-sicad.de/namespaces/va" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><auftragsid>AMGR000000161077</auftragsid><profilkennung>NBABenutzerLA</profilkennung><auftragsnummer>Admin_100413082150_001_0006</auftragsnummer><antragsnummer>Admin_100413082150_0006</antragsnummer><nasoperation>NutzerbezogeneBestandsdatenaktualisierung_NBA</nasoperation><status>beendet</status><startzeitreal>2010-10-13T22:29:43.66646+02:00</startzeitreal><endzeitreal>2010-10-13T22:29:43.66646+02:00</endzeitreal><Message><Category>NOTHING</Category><MessageLevel>Info</MessageLevel><MessageObject><FeatureClass /><Id /></MessageObject><MessageText>Das Ergebnis wurde mit der 3A-Version 6.0.9.3 erstellt.</MessageText><ProcessingTime>2010-10-13T22:29:43.66646+02:00</ProcessingTime></Message></Protocol> + true + Admin_100413082150_0006 + + + + + + + + true + + + + + + + + Admin_100413082150_001_0006 + + + NBABenutzerLA + 2010-10-13T20:10:14Z + 16 + 130 + 484560.000 5753705.000 + + + diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..ca18a72cc503 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..d3c0d9e20c02 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000001.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..b4ed54fbfb33 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..29323984e52a Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000002.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..29b5907954ae Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..4cf22da58b1f Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000003.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..e731d3f0c724 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..0209415ef5ba Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000004.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..d717f9fa1a7c Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..259a71f00d2c Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000005.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..7c8b607cb27b Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..92567c81d8c1 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000006.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..3e11ac8a531f Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..8a2df70bfbfb Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000007.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbindexes b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..cc24e2a06b9b Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbindexes differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtable b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..5cde63fc1c8e Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtable differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtablx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..c8318b15c834 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.gdbtablx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.spx b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.spx new file mode 100644 index 000000000000..44769469081c Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/a00000009.spx differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/gdb b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/gdb new file mode 100644 index 000000000000..506f9c628294 Binary files /dev/null and b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/gdb differ diff --git a/autotest/ogr/data/openfilegdb/polygon_golden.gdb/timestamps b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/timestamps new file mode 100644 index 000000000000..05d2b9440ec0 --- /dev/null +++ b/autotest/ogr/data/openfilegdb/polygon_golden.gdb/timestamps @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/autotest/ogr/data/parquet/poly.parquet b/autotest/ogr/data/parquet/poly.parquet new file mode 100644 index 000000000000..43aac1f46aef Binary files /dev/null and b/autotest/ogr/data/parquet/poly.parquet differ diff --git a/autotest/ogr/data/pdf/recursive_resources_and_oc_name_and_empty_ocg_name.pdf b/autotest/ogr/data/pdf/recursive_resources_and_oc_name_and_empty_ocg_name.pdf new file mode 100644 index 000000000000..a2d7811825b3 Binary files /dev/null and b/autotest/ogr/data/pdf/recursive_resources_and_oc_name_and_empty_ocg_name.pdf differ diff --git a/autotest/ogr/data/pydrivers/ogr_DUMMY.py b/autotest/ogr/data/pydrivers/ogr_DUMMY.py index 1e3f64976e45..4760902927ac 100644 --- a/autotest/ogr/data/pydrivers/ogr_DUMMY.py +++ b/autotest/ogr/data/pydrivers/ogr_DUMMY.py @@ -25,13 +25,13 @@ from gdal_python_driver import BaseDataset, BaseDriver, BaseLayer except ImportError: # To be able to run in standalone mode - class BaseDriver(object): + class BaseDriver: pass - class BaseDataset(object): + class BaseDataset: pass - class BaseLayer(object): + class BaseLayer: pass diff --git a/autotest/ogr/data/shp/poly_golden/poly.dbf b/autotest/ogr/data/shp/poly_golden/poly.dbf new file mode 100644 index 000000000000..ad76f9f42a5b Binary files /dev/null and b/autotest/ogr/data/shp/poly_golden/poly.dbf differ diff --git a/autotest/ogr/data/shp/poly_golden/poly.prj b/autotest/ogr/data/shp/poly_golden/poly.prj new file mode 100644 index 000000000000..fec0ee28909b --- /dev/null +++ b/autotest/ogr/data/shp/poly_golden/poly.prj @@ -0,0 +1 @@ +PROJCS["British_National_Grid",GEOGCS["GCS_OSGB_1936",DATUM["D_OSGB_1936",SPHEROID["Airy_1830",6377563.396,299.3249646]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",-100000.0],PARAMETER["Central_Meridian",-2.0],PARAMETER["Scale_Factor",0.9996012717],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/autotest/ogr/data/shp/poly_golden/poly.shp b/autotest/ogr/data/shp/poly_golden/poly.shp new file mode 100644 index 000000000000..98951531b18c Binary files /dev/null and b/autotest/ogr/data/shp/poly_golden/poly.shp differ diff --git a/autotest/ogr/data/shp/poly_golden/poly.shx b/autotest/ogr/data/shp/poly_golden/poly.shx new file mode 100644 index 000000000000..134898b3895e Binary files /dev/null and b/autotest/ogr/data/shp/poly_golden/poly.shx differ diff --git a/autotest/ogr/data/xlsx/row_without_r_attribute.xlsx b/autotest/ogr/data/xlsx/row_without_r_attribute.xlsx new file mode 100644 index 000000000000..53fbf6b644cf Binary files /dev/null and b/autotest/ogr/data/xlsx/row_without_r_attribute.xlsx differ diff --git a/autotest/ogr/data/xodr/empty.xodr b/autotest/ogr/data/xodr/empty.xodr new file mode 100644 index 000000000000..4668c97ba61e --- /dev/null +++ b/autotest/ogr/data/xodr/empty.xodr @@ -0,0 +1,7 @@ + + +
    +
    + + +
    diff --git a/autotest/ogr/ogr_adbc.py b/autotest/ogr/ogr_adbc.py new file mode 100755 index 000000000000..8ee1da12a50f --- /dev/null +++ b/autotest/ogr/ogr_adbc.py @@ -0,0 +1,379 @@ +#!/usr/bin/env pytest +############################################################################### +# $Id$ +# +# Project: GDAL/OGR Test Suite +# Purpose: Test read functionality for OGR ADBC driver. +# Author: Even Rouault +# +############################################################################### +# Copyright (c) 2024, Even Rouault +# +# SPDX-License-Identifier: MIT +############################################################################### + +import gdaltest +import pytest + +from osgeo import gdal, ogr + + +def _has_adbc_driver_manager(): + drv = gdal.GetDriverByName("ADBC") + return drv and drv.GetMetadataItem("HAS_ADBC_DRIVER_MANAGER") + + +pytestmark = [ + pytest.mark.require_driver("ADBC"), + pytest.mark.skipif( + not _has_adbc_driver_manager(), + reason="ADBC driver built without AdbcDriverManager", + ), +] + +############################################################################### + + +def _has_sqlite_driver(): + import ctypes + + try: + return ctypes.cdll.LoadLibrary("libadbc_driver_sqlite.so") is not None + except Exception: + return False + + +############################################################################### + + +def test_ogr_adbc_driver_open_option(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "ADBC:", gdal.OF_VECTOR, open_options=["ADBC_DRIVER=adbc_driver_sqlite"] + ) as ds: + assert ds.GetLayerCount() == 0 + with ds.ExecuteSQL("SELECT sqlite_version()") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f + assert f.GetField(0).startswith("3.") + + +############################################################################### + + +def test_ogr_adbc_invalid_driver(): + + with pytest.raises(Exception): + gdal.OpenEx( + "ADBC:", gdal.OF_VECTOR, open_options=["ADBC_DRIVER=invalid_driver"] + ) + + +############################################################################### + + +def test_ogr_adbc_invalid_dataset(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with pytest.raises(Exception): + gdal.OpenEx( + "ADBC:/i/do/not/exist.db", + gdal.OF_VECTOR, + open_options=["ADBC_DRIVER=adbc_driver_sqlite"], + ) + + +############################################################################### + + +def test_ogr_adbc_sqlite3(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "data/sqlite/poly_spatialite.sqlite", gdal.OF_VECTOR, allowed_drivers=["ADBC"] + ) as ds: + assert ds.GetLayerCount() == 13 + assert ds.GetLayer(-1) is None + assert ds.GetLayer(ds.GetLayerCount()) is None + lyr = ds.GetLayer(0) + assert lyr.TestCapability(ogr.OLCFastGetArrowStream) + + +############################################################################### + + +def test_ogr_adbc_sql_open_option(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "ADBC:data/sqlite/poly_spatialite.sqlite", + gdal.OF_VECTOR, + open_options=["SQL=SELECT * FROM poly"], + ) as ds: + assert ds.GetLayerCount() == 1 + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 10 + + +############################################################################### + + +def test_ogr_adbc_invalid_sql(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with pytest.raises(Exception): + gdal.OpenEx( + "ADBC:data/sqlite/poly_spatialite.sqlite", + gdal.OF_VECTOR, + open_options=["SQL=SELECT * FROM"], + ) + + +############################################################################### + + +def test_ogr_adbc_generic_open_option(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "ADBC:", + gdal.OF_VECTOR, + open_options=[ + "ADBC_DRIVER=adbc_driver_sqlite", + "ADBC_OPTION_uri=data/sqlite/poly_spatialite.sqlite", + ], + ) as ds: + assert ds.GetLayerCount() == 13 + + +############################################################################### + + +def test_ogr_adbc_execute_sql(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "data/sqlite/poly_spatialite.sqlite", + gdal.OF_VECTOR, + open_options=["SQL="], + allowed_drivers=["ADBC"], + ) as ds: + assert ds.GetLayerCount() == 0 + with ds.ExecuteSQL("SELECT * FROM poly") as lyr: + assert lyr.GetFeatureCount() == 10 + + +############################################################################### + + +def _has_libduckdb(): + import ctypes + + try: + return ctypes.cdll.LoadLibrary("libduckdb.so") is not None + except Exception: + return False + + +############################################################################### + + +def test_ogr_adbc_duckdb_parquet(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + with gdal.OpenEx( + "data/parquet/partitioned_flat/part.0.parquet", + gdal.OF_VECTOR, + allowed_drivers=["ADBC"], + ) as ds: + assert ds.GetLayerCount() == 1 + lyr = ds.GetLayer(0) + assert lyr.TestCapability(ogr.OLCFastFeatureCount) + assert lyr.GetFeatureCount() == 3 + + +############################################################################### + + +def test_ogr_adbc_duckdb_parquet_with_sql_open_option(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + with gdal.OpenEx( + "data/parquet/partitioned_flat/part.0.parquet", + gdal.OF_VECTOR, + allowed_drivers=["ADBC"], + open_options=["SQL=SELECT * FROM part.0 ORDER BY one DESC LIMIT 2"], + ) as ds: + assert ds.GetLayerCount() == 1 + lyr = ds.GetLayer(0) + assert lyr.TestCapability(ogr.OLCFastFeatureCount) == 0 + assert lyr.GetFeatureCount() == 2 + + +############################################################################### + + +def test_ogr_adbc_duckdb_parquet_with_spatial(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + if gdaltest.is_travis_branch("ubuntu_2404"): + # Works locally for me when replicating the Dockerfile ... + pytest.skip("fails on ubuntu_2404 for unknown reason") + + with gdal.OpenEx( + "data/parquet/poly.parquet", + gdal.OF_VECTOR, + allowed_drivers=["ADBC"], + open_options=[ + "PRELUDE_STATEMENTS=INSTALL spatial", + "PRELUDE_STATEMENTS=LOAD spatial", + ], + ) as ds: + with ds.ExecuteSQL( + "SELECT ST_AsText(geometry) FROM read_parquet('data/parquet/poly.parquet')" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0).startswith("POLYGON") + + +############################################################################### +# Run test_ogrsf on a SQLite3 database + + +def test_ogr_adbc_test_ogrsf_sqlite3(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + + " -ro ADBC:data/sqlite/first_geometry_null.db" + ) + + assert "INFO" in ret + assert "ERROR" not in ret + + +############################################################################### +# Run test_ogrsf on a single Parquet file + + +def test_ogr_adbc_test_ogrsf_parquet(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + + " -ro ADBC:data/parquet/partitioned_flat/part.0.parquet" + ) + + assert "INFO" in ret + assert "ERROR" not in ret + + +############################################################################### +# Run test_ogrsf on a partitioned Parquet dataset + + +def test_ogr_adbc_test_ogrsf_parquet_filename_with_glob(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + + " -ro ADBC:data/parquet/partitioned_flat/*.parquet" + ) + + assert "INFO" in ret + assert "ERROR" not in ret + + +############################################################################### +# Run test_ogrsf on a DuckDB dataset + + +def test_ogr_adbc_test_ogrsf_duckdb(): + + if not _has_libduckdb(): + pytest.skip("libduckdb.so missing") + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + " -ro ADBC:data/duckdb/poly.duckdb" + ) + + assert "INFO" in ret + assert "ERROR" not in ret + + +############################################################################### + + +def test_ogr_adbc_layer_list(): + + if not _has_sqlite_driver(): + pytest.skip("adbc_driver_sqlite missing") + + with gdal.OpenEx( + "data/sqlite/poly_spatialite.sqlite", gdal.OF_VECTOR, allowed_drivers=["ADBC"] + ) as ds: + assert ds.GetLayerCount() == 13 + assert ds.GetLayerByName("table_list") + assert ds.GetLayerCount() == 14 + # Re-issue GetLayerByName() to check it has been added to the list + # of known layers and is no instantiated twice. + lyr = ds.GetLayerByName("table_list") + assert lyr + assert ds.GetLayerCount() == 14 + assert lyr.GetFeatureCount() == 14 + found = False + for f in lyr: + if ( + f["catalog_name"] == "main" + and f["table_name"] == "spatial_ref_sys" + and f["table_type"] == "table" + ): + found = True + assert found diff --git a/autotest/ogr/ogr_aivector.py b/autotest/ogr/ogr_aivector.py new file mode 100755 index 000000000000..32c194666cc9 --- /dev/null +++ b/autotest/ogr/ogr_aivector.py @@ -0,0 +1,33 @@ +#!/usr/bin/env pytest +############################################################################### +# $Id$ +# +# Project: GDAL/OGR Test Suite +# Purpose: Test read functionality for OGR AIVector driver. +# Author: Even Rouault +# +############################################################################### +# Copyright (c) 2024, Even Rouault +# +# SPDX-License-Identifier: MIT +############################################################################### + +import gdaltest +import pytest + +pytestmark = pytest.mark.require_driver("AIVector") + + +def test_ogr_aivector_test_ogrsf(): + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + " -ro AIVector:foo.bin" + ) + + assert "INFO" in ret + assert "ERROR" not in ret diff --git a/autotest/ogr/ogr_arrow.py b/autotest/ogr/ogr_arrow.py index cba6928589bc..8ffbe0c11913 100755 --- a/autotest/ogr/ogr_arrow.py +++ b/autotest/ogr/ogr_arrow.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -793,4 +777,149 @@ def test_ogr_arrow_vsi_arrow_file_system(): if version < 16: pytest.skip("requires Arrow >= 16.0.0") - ogr.Open("vsi://data/arrow/test.feather") + ogr.Open("gdalvsi://data/arrow/test.feather") + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_ogr_arrow_string_view(): + + version = int( + ogr.GetDriverByName("ARROW").GetMetadataItem("ARROW_VERSION").split(".")[0] + ) + if version < 15: + pytest.skip("requires Arrow >= 15") + + with ogr.Open("data/arrow/stringview.feather") as ds: + lyr = ds.GetLayer(0) + f = lyr.GetNextFeature() + assert f["stringview"] == "foo" + assert f["list_stringview"] is None + assert f["list_of_list_stringview"] is None + assert f["map_stringview"] is None + + f = lyr.GetNextFeature() + assert f["stringview"] == "bar" + assert f["list_stringview"] == [""] + assert f["list_of_list_stringview"] == "[null]" + assert f["map_stringview"] == "{}" + + f = lyr.GetNextFeature() + assert f["stringview"] == "looooooooooong string" + assert f["list_stringview"] == ["foo", "bar", "looooooooooong string"] + assert f["list_of_list_stringview"] == '[["foo","bar","looooooooooong string"]]' + assert f["map_stringview"] == '{"x":"x_val","y":null}' + + +############################################################################### + + +@gdaltest.enable_exceptions() +def test_ogr_arrow_binary_view(): + + version = int( + ogr.GetDriverByName("ARROW").GetMetadataItem("ARROW_VERSION").split(".")[0] + ) + if version < 15: + pytest.skip("requires Arrow >= 15") + + with ogr.Open("data/arrow/binaryview.feather") as ds: + lyr = ds.GetLayer(0) + f = lyr.GetNextFeature() + assert f.GetFieldAsBinary("binaryview") == b"foo" + f = lyr.GetNextFeature() + assert f.GetFieldAsBinary("binaryview") == b"bar" + f = lyr.GetNextFeature() + assert f.GetFieldAsBinary("binaryview") == b"looooooooooong binary" + + +############################################################################### + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize( + "geom_type,encoding,expected_arrow_type", + [ + ( + ogr.wkbPoint, + "GEOARROW_STRUCT", + "struct", + ), + ( + ogr.wkbPoint, + "GEOARROW_INTERLEAVED", + "fixed_size_list[2]", + ), + ( + ogr.wkbLineString, + "GEOARROW_STRUCT", + "list>", + ), + ( + ogr.wkbLineString, + "GEOARROW_INTERLEAVED", + "list[2]>", + ), + ( + ogr.wkbPolygon, + "GEOARROW_STRUCT", + "list>>", + ), + ( + ogr.wkbPolygon, + "GEOARROW_INTERLEAVED", + "list[2]>>", + ), + ( + ogr.wkbMultiPoint, + "GEOARROW_STRUCT", + "list>", + ), + ( + ogr.wkbMultiPoint, + "GEOARROW_INTERLEAVED", + "list[2]>", + ), + ( + ogr.wkbMultiLineString, + "GEOARROW_STRUCT", + "list>>", + ), + ( + ogr.wkbMultiLineString, + "GEOARROW_INTERLEAVED", + "list[2]>>", + ), + ( + ogr.wkbMultiPolygon, + "GEOARROW_STRUCT", + "list>>>", + ), + ( + ogr.wkbMultiPolygon, + "GEOARROW_INTERLEAVED", + "list[2]>>>", + ), + ], +) +def test_ogr_arrow_check_geoarrow_types( + tmp_path, geom_type, encoding, expected_arrow_type +): + pytest.importorskip("pyarrow") + import pyarrow.feather + + filename = str(tmp_path / "out.feather") + srs = osr.SpatialReference() + srs.ImportFromEPSG(4326) + with ogr.GetDriverByName("ARROW").CreateDataSource(filename) as ds: + ds.CreateLayer( + "test", + geom_type=geom_type, + srs=srs, + options=["GEOMETRY_ENCODING=" + encoding], + ) + + schema = pyarrow.feather.read_table(filename).schema + assert str(schema.field("geometry").type) == expected_arrow_type diff --git a/autotest/ogr/ogr_as_sqlite_extension.py b/autotest/ogr/ogr_as_sqlite_extension.py index 4dd19201ce89..6efa4ccf0317 100755 --- a/autotest/ogr/ogr_as_sqlite_extension.py +++ b/autotest/ogr/ogr_as_sqlite_extension.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### # This file is meant at being run by ogr_virtualogr_3() diff --git a/autotest/ogr/ogr_avc.py b/autotest/ogr/ogr_avc.py index 7e154ded3e3d..cd2bcd0aaaf7 100755 --- a/autotest/ogr/ogr_avc.py +++ b/autotest/ogr/ogr_avc.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_basic_test.py b/autotest/ogr/ogr_basic_test.py index ee33cc6d5b8a..09703b7deaf5 100755 --- a/autotest/ogr/ogr_basic_test.py +++ b/autotest/ogr/ogr_basic_test.py @@ -1228,6 +1228,8 @@ def test_driver_open_throw_2(): with gdaltest.enable_exceptions(): drv = ogr.GetDriverByName("MapInfo File") + if not drv: + pytest.skip("MapInfo driver not available") assert isinstance(drv, ogr.Driver) diff --git a/autotest/ogr/ogr_cad.py b/autotest/ogr/ogr_cad.py index 6909f87b19e4..906144e70941 100755 --- a/autotest/ogr/ogr_cad.py +++ b/autotest/ogr/ogr_cad.py @@ -12,23 +12,7 @@ # Copyright (c) 2016 Alexandr Borzykh # Copyright (c) 2016-2019, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ################################################################################ diff --git a/autotest/ogr/ogr_carto.py b/autotest/ogr/ogr_carto.py index cd593aedfeaf..30cf4d025291 100755 --- a/autotest/ogr/ogr_carto.py +++ b/autotest/ogr/ogr_carto.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import uuid diff --git a/autotest/ogr/ogr_csw.py b/autotest/ogr/ogr_csw.py index 653de9c73981..715b75f12be5 100755 --- a/autotest/ogr/ogr_csw.py +++ b/autotest/ogr/ogr_csw.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -46,9 +30,14 @@ def module_disable_exceptions(): ############################################################################### @pytest.fixture(autouse=True, scope="module") def setup_and_cleanup(): + + vsimem_hidden_before = gdal.ReadDirRecursive("/vsimem/.#!HIDDEN!#.") + with gdal.config_option("CPL_CURL_ENABLE_VSIMEM", "YES"): yield + assert gdal.ReadDirRecursive("/vsimem/.#!HIDDEN!#.") == vsimem_hidden_before + ############################################################################### # Test underlying OGR drivers diff --git a/autotest/ogr/ogr_dgnv8.py b/autotest/ogr/ogr_dgnv8.py index 1b7b77262c3c..aa3c9c61cf46 100755 --- a/autotest/ogr/ogr_dgnv8.py +++ b/autotest/ogr/ogr_dgnv8.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_dwg.py b/autotest/ogr/ogr_dwg.py index 9f9e7be46236..17df5abb4921 100755 --- a/autotest/ogr/ogr_dwg.py +++ b/autotest/ogr/ogr_dwg.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017, Jorge Gustavo Rocha # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_dxf.py b/autotest/ogr/ogr_dxf.py index d2ecbd72d34d..a7570c3fe3c0 100644 --- a/autotest/ogr/ogr_dxf.py +++ b/autotest/ogr/ogr_dxf.py @@ -11,23 +11,7 @@ # Copyright (c) 2009, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -452,20 +436,28 @@ def test_ogr_dxf_12(tmp_path): dst_feat = ogr.Feature(feature_def=lyr.GetLayerDefn()) dst_feat.SetGeometryDirectly(ogr.CreateGeometryFromWkt("LINESTRING(10 12, 60 65)")) + dst_feat.SetFID(0) lyr.CreateFeature(dst_feat) + # 80 is the minimum handle value we set in case of inapproriate or unset + # initial FID value + assert dst_feat.GetFID() >= 80 dst_feat = None dst_feat = ogr.Feature(feature_def=lyr.GetLayerDefn()) dst_feat.SetGeometryDirectly( ogr.CreateGeometryFromWkt("POLYGON((0 0,100 0,100 100,0 0))") ) + dst_feat.SetFID(79) lyr.CreateFeature(dst_feat) + assert dst_feat.GetFID() == 79 dst_feat = None # Test 25D linestring with constant Z (#5210) dst_feat = ogr.Feature(feature_def=lyr.GetLayerDefn()) dst_feat.SetGeometryDirectly(ogr.CreateGeometryFromWkt("LINESTRING(1 2 10,3 4 10)")) + dst_feat.SetFID(79) lyr.CreateFeature(dst_feat) + assert dst_feat.GetFID() > 79 dst_feat = None # Test 25D linestring with different Z (#5210) @@ -1125,7 +1117,7 @@ def test_ogr_dxf_20(): ogrtest.check_feature_geometry( feat, - "LINESTRING (10.75 62.75,20.637752769146068 63.434832501489716,29.283239084385464 63.396838394381845,36.766943814562865 62.711565975596599,43.169351828522906 61.454563542054103,48.570947995110252 59.70137939067456,53.05221718316956 57.527561818378146,56.693644261545501 55.008659122085049,59.575714099082703 52.220219598715438,61.778911564625851 49.237791545189509,63.383721527019588 46.136923258427423,64.470628855108572 42.993163035349369,65.120118417737459 39.882059172875508,65.412419131869868 36.878358785215056,65.417809785093752 34.025663008687722,65.193643595004147 31.327113252708507,64.796409941597645 28.783146935042897,64.282598204870823 26.394201473456341,63.708697764820236 24.16071428571431,63.131198001442392 22.083122789582241,62.606588294733939 20.161864402825621,62.191358024691354 18.397376543209894,61.941996571311265 16.790096628500525,61.914993314590184 15.340462076462975,62.166837634524704 14.0489103048627,62.754018911111373 12.915878731465167,63.723652286703427 11.940700981548817,65.053571428571416 11.114552964042769,66.690557841792398 10.424954275262921,68.581246558980226 9.859407264767562,70.672272612748785 9.405414282114966,72.910271035711943 9.050477676863418,75.241876860483572 8.782099798571203,77.613725119677511 8.587782996796603,79.97245084590763 8.4550296210979,82.264689071787842 8.371342021033378,84.437074829931987 8.324222546161321,86.436243152953921 8.301173546040012,88.208926721776336 8.289771106365336,89.722559658784164 8.293223374005688,90.990763736417563 8.349615688917151,92.033410218878885 8.501752503862612,92.870370370370395 8.792438271604945,93.521515455094473 9.264477444907039,94.006716737253413 9.960674476531764,94.345845481049565 10.923833819242011,94.558772950685281 12.196759925800654,94.665370410362868 13.82225724897058,94.685509124284636 15.843130241514663,94.639060356652948 18.302183356195791,94.545895371670113 21.242221045776841,94.421471763308503 24.702030018356666,94.215205541358216 28.660279617432039,93.825673773330607 33.049360720184715,93.15014577259474 37.800473760933045,92.085890852519697 42.844819173995376,90.530178326474584 48.113597393690064,88.380277507828495 53.538008854335445,85.533457709950525 59.049253990249873,81.886988246209697 64.578533235751706,77.338138429975174 70.057047025159264,71.784177574615995 75.415995792790937,65.122374993501282 80.586579972965055,57.25 85.5)", + "LINESTRING Z (10.75 62.75 0,20.6377527691461 63.4348325014897 0,29.2832390843855 63.3968383943819 0,36.7669438145629 62.7115659755966 0,43.1693518285229 61.4545635420541 0,48.5709479951103 59.7013793906746 0,53.0522171831696 57.5275618183782 0,56.6936442615455 55.0086591220851 0,59.5757140990827 52.2202195987154 0,61.7789115646259 49.2377915451895 0,63.3837215270196 46.1369232584274 0,64.4706288551086 42.9931630353494 0,65.1201184177375 39.8820591728755 0,65.4124191318699 36.8783587852151 0,65.4178097850938 34.0256630086877 0,65.1936435950041 31.3271132527085 0,64.7964099415976 28.7831469350429 0,64.2825982048708 26.3942014734563 0,63.7086977648202 24.1607142857143 0,63.1311980014424 22.0831227895822 0,62.6065882947339 20.1618644028256 0,62.1913580246914 18.3973765432099 0,61.9419965713113 16.7900966285005 0,61.9149933145902 15.340462076463 0,62.1668376345247 14.0489103048627 0,62.7540189111114 12.9158787314652 0,63.7236522867034 11.9407009815488 0,65.0535714285714 11.1145529640428 0,66.6905578417924 10.4249542752629 0,68.5812465589803 9.85940726476756 0,70.6722726127488 9.40541428211496 0,72.9102710357119 9.05047767686342 0,75.2418768604836 8.7820997985712 0,77.6137251196775 8.5877829967966 0,79.9724508459076 8.4550296210979 0,82.2646890717878 8.37134202103338 0,84.4370748299319 8.32422254616132 0,86.4362431529539 8.30117354604001 0,88.2089267217763 8.28977110636533 0,89.7225596587841 8.29322337400568 0,90.9907637364175 8.34961568891715 0,92.0334102188788 8.5017525038626 0,92.8703703703704 8.79243827160492 0,93.5215154550944 9.264477444907 0,94.0067167372534 9.9606744765317 0,94.3458454810496 10.9238338192419 0,94.5587729506853 12.1967599258005 0,94.6653704103629 13.8222572489704 0,94.6855091242846 15.8431302415145 0,94.6390603566529 18.3021833561955 0,94.5458953716701 21.2422210457765 0,94.4214717633085 24.7020300183563 0,94.2152055413583 28.6602796174316 0,93.8256737733306 33.0493607201842 0,93.1501457725948 37.8004737609325 0,92.0858908525198 42.8448191739948 0,90.5301783264748 48.1135973936895 0,88.3802775078288 53.5380088543349 0,85.5334577099508 59.0492539902493 0,81.8869882462101 64.5785332357511 0,77.3381384299757 70.0570470251587 0,71.7841775746166 75.4159957927904 0,65.122374993502 80.5865799729645 0,57.25 85.5 0)", ) ds = None @@ -1366,21 +1358,21 @@ def test_ogr_dxf_29(): feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 2, 2.10256409645081 2.15371131896973, 2.20512819290161 2.3066132068634, 2.307692527771 2.4578971862793, 2.41025638580322 2.6067533493042, 2.51282024383545 2.75237274169922, 2.61538457870483 2.89394640922546, 2.71794891357422 3.03066444396973, 2.82051301002502 3.16171884536743, 2.92307710647583 3.28629970550537, 3.02564096450806 3.40359783172607, 3.12820529937744 3.51280379295349, 3.23076939582825 3.61310863494873, 3.33333325386047 3.70370388031006, 3.43589782714844 3.78377938270569, 3.53846144676208 3.85252642631531, 3.64102602005005 3.90913581848145, 3.74358987808228 3.95279765129089, 3.84615445137024 3.98270392417908, 3.94871830940247 3.99804472923279, 4.05128240585327 3.99804425239563, 4.15384674072266 3.9827036857605, 4.25641107559204 3.95279765129089, 4.35897541046143 3.90913534164429, 4.46153926849365 3.85252571105957, 4.56410360336304 3.78377866744995, 4.66666793823242 3.70370292663574, 4.76923179626465 3.61310815811157, 4.87179613113403 3.51280236244202, 4.97436046600342 3.40359592437744, 5.07692432403564 3.2862982749939, 5.17948865890503 3.16171741485596, 5.28205299377441 3.03066277503967, 5.38461685180664 2.89394426345825, 5.48718070983887 2.75237035751343, 5.58974552154541 2.60675096511841, 5.69230937957764 2.45789456367493, 5.79487323760986 2.30661058425903, 5.89743757247925 2.15370845794678, 6 2)", + "LINESTRING Z (2 2 0,2.1025641025641 2.15371128980596 0,2.2051282051282 2.30661339537079 0,2.30769230769231 2.45789713245335 0,2.41025641025641 2.60675331681249 0,2.51282051282051 2.75237276420708 0,2.61538461538461 2.89394629039599 0,2.71794871794872 3.03066471113808 0,2.82051282051282 3.16171884219221 0,2.92307692307692 3.28629949931725 0,3.02564102564102 3.40359749827205 0,3.12820512820513 3.51280365481549 0,3.23076923076923 3.61310878470642 0,3.33333333333333 3.7037037037037 0,3.43589743589744 3.78377922756621 0,3.53846153846154 3.8525261720528 0,3.64102564102564 3.90913535292233 0,3.74358974358974 3.95279758593368 0,3.84615384615384 3.9827036868457 0,3.94871794871795 3.99804447141725 0,4.05128205128205 3.99804447141725 0,4.15384615384615 3.9827036868457 0,4.25641025641026 3.95279758593368 0,4.35897435897436 3.90913535292233 0,4.46153846153846 3.8525261720528 0,4.56410256410256 3.78377922756621 0,4.66666666666667 3.7037037037037 0,4.76923076923077 3.61310878470642 0,4.87179487179487 3.51280365481549 0,4.97435897435897 3.40359749827205 0,5.07692307692308 3.28629949931725 0,5.17948717948718 3.16171884219221 0,5.28205128205128 3.03066471113808 0,5.38461538461539 2.89394629039599 0,5.48717948717949 2.75237276420708 0,5.58974358974359 2.60675331681249 0,5.69230769230769 2.45789713245334 0,5.7948717948718 2.30661339537079 0,5.8974358974359 2.15371128980596 0,6 2 0)", ) # spline 261, weight(3) = 2.0 feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 2, 2.10976576805115 2.16451454162598, 2.23113083839417 2.34563326835632, 2.35994720458984 2.53639197349548, 2.49239826202393 2.73041176795959, 2.62522411346436 2.92225241661072, 2.75582838058472 3.10756635665894, 2.88229131698608 3.2831084728241, 3.00331926345825 3.44663000106812, 3.11815142631531 3.59672045707703, 3.2264621257782 3.73262500762939, 3.32825922966003 3.85407567024231, 3.42379808425903 3.96113181114197, 3.51351404190063 4.05405473709106, 3.59796214103699 4.13319540023804, 3.67778849601746 4.19891929626465, 3.75369834899902 4.25152969360352, 3.82645153999329 4.29121112823486, 3.89685702323914 4.31797361373901, 3.96579027175903 4.33159732818604, 4.03421020507812 4.33159732818604, 4.1031436920166 4.31797361373901, 4.17354917526245 4.29121017456055, 4.24630165100098 4.2515287399292, 4.32221221923828 4.19891929626465, 4.40203857421875 4.13319492340088, 4.48648738861084 4.05405378341675, 4.57620286941528 3.96113133430481, 4.67174291610718 3.85407471656799, 4.77353954315186 3.73262333869934, 4.88184928894043 3.59671831130981, 4.99668216705322 3.44662809371948, 5.11771011352539 3.28310608863831, 5.24417400360107 3.10756373405457, 5.37477827072144 2.92224931716919, 5.50760412216187 2.73040890693665, 5.64005517959595 2.5363883972168, 5.76887130737305 2.34562969207764, 5.89023685455322 2.16451120376587, 6 2)", + "LINESTRING Z (2 2 0,2.10976572340247 2.16451423293308 0,2.23113089996843 2.34563306806665 0,2.35994706660785 2.5363917071019 0,2.4923982030663 2.7304119838212 0,2.62522401782792 2.92225217784288 0,2.7558282208589 3.10756646216769 0,2.88229155950089 3.2831087138637 0,3.00331913560022 3.44663029387883 0,3.11815132314573 3.5967200894521 0,3.22646181024907 3.73262490129686 0,3.32825875170488 3.85407546924726 0,3.42379815888169 3.96113194681214 0,3.51351351351351 4.05405405405405 0,3.59796229770158 4.13319556415278 0,3.67778836987607 4.19891960597394 0,3.75369845584408 4.25152969753051 0,3.82645109024315 4.29121073470179 0,3.89685688129387 4.31797375648459 0,3.96578985841365 4.33159771032714 0,4.03421014158635 4.33159771032714 0,4.10314311870613 4.31797375648459 0,4.17354890975685 4.29121073470179 0,4.24630154415592 4.25152969753051 0,4.32221163012393 4.19891960597394 0,4.40203770229842 4.13319556415278 0,4.48648648648649 4.05405405405405 0,4.57620184111831 3.96113194681214 0,4.67174124829512 3.85407546924726 0,4.77353818975093 3.73262490129686 0,4.88184867685427 3.59672008945211 0,4.99668086439978 3.44663029387883 0,5.11770844049911 3.2831087138637 0,5.24417177914111 3.10756646216769 0,5.37477598217208 2.92225217784288 0,5.5076017969337 2.7304119838212 0,5.64005293339215 2.53639170710189 0,5.76886910003157 2.34563306806665 0,5.89023427659753 2.16451423293307 0,6 2 0)", ) # spline 262, weight(3) = 0.5 feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 2, 2.09894275665283 2.14827871322632, 2.19183802604675 2.28667020797729, 2.28029608726501 2.41674375534058, 2.36573505401611 2.53972935676575, 2.4494321346283 2.65657186508179, 2.53256177902222 2.76796913146973, 2.61621570587158 2.87439489364624, 2.70142364501953 2.97611308097839, 2.78915071487427 3.07318329811096, 2.88029623031616 3.16546249389648, 2.97567653656006 3.25260472297668, 3.07599782943726 3.33406257629395, 3.18181824684143 3.40909075737, 3.29349946975708 3.4767644405365, 3.4111499786377 3.53600478172302, 3.53456783294678 3.58562660217285, 3.66318273544312 3.62440752983093, 3.79601716995239 3.6511766910553, 3.93166828155518 3.66492199897766, 4.06833267211914 3.66492199897766, 4.20398426055908 3.65117692947388, 4.33681774139404 3.62440729141235, 4.4654335975647 3.58562660217285, 4.58885097503662 3.53600406646729, 4.70650196075439 3.47676372528076, 4.81818294525146 3.40909028053284, 4.92400360107422 3.33406162261963, 5.02432489395142 3.25260376930237, 5.11970520019531 3.16546106338501, 5.21085071563721 3.07318210601807, 5.29857730865479 2.9761118888855, 5.38378524780273 2.87439346313477, 5.46744012832642 2.76796770095825, 5.55056858062744 2.65656995773315, 5.63426637649536 2.53972721099854, 5.71970558166504 2.41674160957336, 5.8081636428833 2.2866678237915, 5.9010591506958 2.14827609062195, 6 2)", + "LINESTRING Z (2 2 0,2.09894267472891 2.14827889065297 0,2.1918380517297 2.28667017645161 0,2.28029602220166 2.41674375578168 0,2.36573488380154 2.53972930350242 0,2.44943227756881 2.65657187049601 0,2.53256150506512 2.76796912686927 0,2.6162160195058 2.87439499253976 0,2.70142356019971 2.9761131424117 0,2.78915046059365 3.07318321392016 0,2.88029601503322 3.1654623297623 0,2.97567642514756 3.25260468248623 0,3.07599781301257 3.33406232914161 0,3.18181818181818 3.40909090909091 0,3.29349914490214 3.47676456305555 0,3.41114982578397 3.53600464576074 0,3.53456755043606 3.5856265436821 0,3.66318260330395 3.62440763541344 0,3.79601689800845 3.65117682558841 0,3.93166808931219 3.66492205400063 0,4.06833191068781 3.66492205400063 0,4.20398310199155 3.65117682558841 0,4.33681739669604 3.62440763541344 0,4.46543244956394 3.58562654368211 0,4.58885017421603 3.53600464576074 0,4.70650085509786 3.47676456305555 0,4.81818181818182 3.40909090909091 0,4.92400218698742 3.33406232914161 0,5.02432357485243 3.25260468248623 0,5.11970398496678 3.1654623297623 0,5.21084953940635 3.07318321392016 0,5.29857643980029 2.9761131424117 0,5.3837839804942 2.87439499253976 0,5.46743849493488 2.76796912686927 0,5.55056772243119 2.65657187049601 0,5.63426511619847 2.53972930350242 0,5.71970397779834 2.41674375578168 0,5.8081619482703 2.2866701764516 0,5.90105732527109 2.14827889065297 0,6 2 0)", ) ds = None @@ -1399,14 +1391,14 @@ def test_ogr_dxf_30(): feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (14 2, 13.9043273925781 2.11115527153015, 13.82310962677 2.23728489875793, 13.7564849853516 2.3759388923645, 13.7045974731445 2.52466750144958, 13.6675891876221 2.68102264404297, 13.6455984115601 2.84255337715149, 13.6387672424316 3.00681042671204, 13.6472396850586 3.17134499549866, 13.6711559295654 3.33370733261108, 13.7106552124023 3.49144792556763, 13.7658815383911 3.64211750030518, 13.8369770050049 3.78326630592346, 13.9240808486938 3.9124448299408, 14.0273275375366 4.0272102355957, 14.1460762023926 4.125901222229, 14.2781581878662 4.20836925506592, 14.4212408065796 4.27464532852173, 14.5729866027832 4.32475566864014, 14.7310619354248 4.35873079299927, 14.8931264877319 4.37659645080566, 15.056845664978 4.37838315963745, 15.2198839187622 4.36411762237549, 15.3799018859863 4.33382892608643, 15.5345678329468 4.2875452041626, 15.681544303894 4.22529458999634, 15.8184909820557 4.14710569381714, 15.9430751800537 4.05300617218018, 16.0530071258545 3.94307255744934, 16.1471080780029 3.81848883628845, 16.2252960205078 3.68154096603394, 16.2875461578369 3.53456616401672, 16.3338298797607 3.37990093231201, 16.3641166687012 3.219881772995, 16.3783836364746 3.05684399604797, 16.3765964508057 2.89312481880188, 16.3587284088135 2.73106050491333, 16.3247547149658 2.57298684120178, 16.2746448516846 2.42124080657959, 16.2083702087402 2.27815842628479, 16.1259021759033 2.146075963974, 16.0272102355957 2.02732920646667, 15.9124450683594 1.92408156394958, 15.7832660675049 1.83697760105133, 15.6421175003052 1.7658828496933, 15.4914503097534 1.71065592765808, 15.3337097167969 1.67115533351898, 15.1713457107544 1.6472395658493, 15.0068111419678 1.63876724243164, 14.8425559997559 1.64559710025787, 14.681022644043 1.66758728027344, 14.5246696472168 1.70459699630737, 14.375940322876 1.75648427009583, 14.2372856140137 1.82310783863068, 14.1111574172974 1.90432631969452, 14 2)", + "LINESTRING Z (14 2 0,13.9043277090443 2.1111553863727 0,13.8231089120438 2.23728477691191 0,13.7564850364624 2.3759387050853 0,13.7045975097642 2.5246677043605 0,13.6675877594132 2.68102230820516 0,13.6455972128733 2.84255305008692 0,13.6387672976085 3.00681046347343 0,13.6472394410828 3.17134508183234 0,13.6711550707602 3.33370743863128 0,13.7106556141046 3.49144806733791 0,13.7658824985801 3.64211750141987 0,13.8369771516507 3.7832662743448 0,13.9240810007803 3.91244491958036 0,14.0273290209536 4.02721042307341 0,14.1460754371684 4.12590052075793 0,14.2781581418028 4.20836928118745 0,14.4212408102955 4.27464498985476 0,14.5729871180854 4.32475593225266 0,14.7310607406114 4.35873039387394 0,14.8931253533123 4.37659666021141 0,15.0568446316268 4.37838301675786 0,15.2198822509939 4.36411774900609 0,15.3799018868524 4.3338291424489 0,15.5345672146411 4.28754548257907 0,15.6815419097988 4.22529505488942 0,15.8184896477644 4.14710614487273 0,15.9430741039767 4.0530070380218 0,16.0530070380218 3.94307410397669 0,16.1471061448727 3.81848964776439 0,16.2252950548894 3.68154190979879 0,16.2875454825791 3.53456721464106 0,16.3338291424489 3.37990188685238 0,16.3641177490061 3.21988225099391 0,16.3783830167579 3.05684463162681 0,16.3765966602114 2.89312535331225 0,16.3587303938739 2.73106074061141 0,16.3247559322527 2.57298711808543 0,16.2746449898548 2.4212408102955 0,16.2083692811874 2.27815814180278 0,16.1259005207579 2.14607543716844 0,16.0272104230734 2.02732902095363 0,15.9124449195804 1.92408100078027 0,15.7832662743448 1.83697715165069 0,15.6421175014199 1.76588249858013 0,15.4914480673379 1.71065561410461 0,15.3337074386313 1.67115507076015 0,15.1713450818323 1.64723944108276 0,15.0068104634734 1.63876729760846 0,14.8425530500869 1.64559721287326 0,14.6810223082052 1.66758775941317 0,14.5246677043605 1.70459750976422 0,14.3759387050853 1.75648503646241 0,14.2372847769119 1.82310891204376 0,14.1111553863727 1.90432770904428 0,14 2 0)", ) # spline 24c, closed, recalculate knots feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (14 2, 13.9043273925781 2.11115527153015, 13.82310962677 2.23728489875793, 13.7564849853516 2.3759388923645, 13.7045974731445 2.52466750144958, 13.6675891876221 2.68102264404297, 13.6455984115601 2.84255337715149, 13.6387672424316 3.00681042671204, 13.6472396850586 3.17134499549866, 13.6711559295654 3.33370733261108, 13.7106552124023 3.49144792556763, 13.7658815383911 3.64211750030518, 13.8369770050049 3.78326630592346, 13.9240808486938 3.9124448299408, 14.0273275375366 4.0272102355957, 14.1460762023926 4.125901222229, 14.2781581878662 4.20836925506592, 14.4212408065796 4.27464532852173, 14.5729866027832 4.32475566864014, 14.7310619354248 4.35873079299927, 14.8931264877319 4.37659645080566, 15.056845664978 4.37838315963745, 15.2198839187622 4.36411762237549, 15.3799018859863 4.33382892608643, 15.5345678329468 4.2875452041626, 15.681544303894 4.22529458999634, 15.8184909820557 4.14710569381714, 15.9430751800537 4.05300617218018, 16.0530071258545 3.94307255744934, 16.1471080780029 3.81848883628845, 16.2252960205078 3.68154096603394, 16.2875461578369 3.53456616401672, 16.3338298797607 3.37990093231201, 16.3641166687012 3.219881772995, 16.3783836364746 3.05684399604797, 16.3765964508057 2.89312481880188, 16.3587284088135 2.73106050491333, 16.3247547149658 2.57298684120178, 16.2746448516846 2.42124080657959, 16.2083702087402 2.27815842628479, 16.1259021759033 2.146075963974, 16.0272102355957 2.02732920646667, 15.9124450683594 1.92408156394958, 15.7832660675049 1.83697760105133, 15.6421175003052 1.7658828496933, 15.4914503097534 1.71065592765808, 15.3337097167969 1.67115533351898, 15.1713457107544 1.6472395658493, 15.0068111419678 1.63876724243164, 14.8425559997559 1.64559710025787, 14.681022644043 1.66758728027344, 14.5246696472168 1.70459699630737, 14.375940322876 1.75648427009583, 14.2372856140137 1.82310783863068, 14.1111574172974 1.90432631969452, 14 2)", + "LINESTRING Z (14 2 0,13.9043277090443 2.1111553863727 0,13.8231089120438 2.23728477691191 0,13.7564850364624 2.3759387050853 0,13.7045975097642 2.5246677043605 0,13.6675877594132 2.68102230820516 0,13.6455972128733 2.84255305008692 0,13.6387672976085 3.00681046347343 0,13.6472394410828 3.17134508183234 0,13.6711550707602 3.33370743863128 0,13.7106556141046 3.49144806733791 0,13.7658824985801 3.64211750141987 0,13.8369771516507 3.7832662743448 0,13.9240810007803 3.91244491958036 0,14.0273290209536 4.02721042307341 0,14.1460754371684 4.12590052075793 0,14.2781581418028 4.20836928118745 0,14.4212408102955 4.27464498985476 0,14.5729871180854 4.32475593225266 0,14.7310607406114 4.35873039387394 0,14.8931253533123 4.37659666021141 0,15.0568446316268 4.37838301675786 0,15.2198822509939 4.36411774900609 0,15.3799018868524 4.3338291424489 0,15.5345672146411 4.28754548257907 0,15.6815419097988 4.22529505488942 0,15.8184896477644 4.14710614487273 0,15.9430741039767 4.0530070380218 0,16.0530070380218 3.94307410397669 0,16.1471061448727 3.81848964776439 0,16.2252950548894 3.68154190979879 0,16.2875454825791 3.53456721464106 0,16.3338291424489 3.37990188685238 0,16.3641177490061 3.21988225099391 0,16.3783830167579 3.05684463162681 0,16.3765966602114 2.89312535331225 0,16.3587303938739 2.73106074061141 0,16.3247559322527 2.57298711808543 0,16.2746449898548 2.4212408102955 0,16.2083692811874 2.27815814180278 0,16.1259005207579 2.14607543716844 0,16.0272104230734 2.02732902095363 0,15.9124449195804 1.92408100078027 0,15.7832662743448 1.83697715165069 0,15.6421175014199 1.76588249858013 0,15.4914480673379 1.71065561410461 0,15.3337074386313 1.67115507076015 0,15.1713450818323 1.64723944108276 0,15.0068104634734 1.63876729760846 0,14.8425530500869 1.64559721287326 0,14.6810223082052 1.66758775941317 0,14.5246677043605 1.70459750976422 0,14.3759387050853 1.75648503646241 0,14.2372847769119 1.82310891204376 0,14.1111553863727 1.90432770904428 0,14 2 0)", ) ds = None @@ -1494,20 +1486,20 @@ def test_ogr_dxf_31(): # OGRFeature(entities):10 # EntityHandle (String) = 200 - # LINESTRING (2 2,2.15384615384615 2.15384615384615,2.30769230769231 2.30769230769231,2.46153846153846 2.46153846153846,2.61538461538461 2.61538461538461,2.76923076923077 2.76923076923077,2.92307692307692 2.92307692307692,3.07692307692308 3.07692307692308,3.23076923076923 3.23076923076923,3.38461538461538 3.38461538461538,3.53846153846154 3.53846153846154,3.69230769230769 3.69230769230769,3.84615384615385 3.84615384615385,4 4,4.15384615384615 4.15384615384615,4.30769230769231 4.30769230769231,4.46153846153846 4.46153846153846,4.61538461538462 4.61538461538462,4.76923076923077 4.76923076923077,4.92307692307692 4.92307692307692,5.07692307692308 5.07692307692308,5.23076923076923 5.23076923076923,5.38461538461538 5.38461538461538,5.53846153846154 5.53846153846154,5.69230769230769 5.69230769230769,5.84615384615385 5.84615384615385,6.0 6.0,6.15384615384615 6.15384615384615,6.30769230769231 6.30769230769231,6.46153846153846 6.46153846153846,6.61538461538462 6.61538461538462,6.76923076923077 6.76923076923077,6.92307692307692 6.92307692307692,7.07692307692308 7.07692307692308,7.23076923076923 7.23076923076923,7.38461538461539 7.38461538461539,7.53846153846154 7.53846153846154,7.69230769230769 7.69230769230769,7.84615384615385 7.84615384615385,8 8) + # LINESTRING Z (2 2 0,2.15384615384615 2.15384615384615 0,2.30769230769231 2.30769230769231 0,2.46153846153846 2.46153846153846 0,2.61538461538461 2.61538461538461 0,2.76923076923077 2.76923076923077 0,2.92307692307692 2.92307692307692 0,3.07692307692308 3.07692307692308 0,3.23076923076923 3.23076923076923 0,3.38461538461538 3.38461538461538 0,3.53846153846154 3.53846153846154 0,3.69230769230769 3.69230769230769 0,3.84615384615385 3.84615384615385 0,4 4 0,4.15384615384615 4.15384615384615 0,4.30769230769231 4.30769230769231 0,4.46153846153846 4.46153846153846 0,4.61538461538462 4.61538461538462 0,4.76923076923077 4.76923076923077 0,4.92307692307692 4.92307692307692 0,5.07692307692308 5.07692307692308 0,5.23076923076923 5.23076923076923 0,5.38461538461538 5.38461538461538 0,5.53846153846154 5.53846153846154 0,5.69230769230769 5.69230769230769 0,5.84615384615385 5.84615384615385 0,6.0 6.0 0,6.15384615384615 6.15384615384615 0,6.30769230769231 6.30769230769231 0,6.46153846153846 6.46153846153846 0,6.61538461538462 6.61538461538462 0,6.76923076923077 6.76923076923077 0,6.92307692307692 6.92307692307692 0,7.07692307692308 7.07692307692308 0,7.23076923076923 7.23076923076923 0,7.38461538461539 7.38461538461539 0,7.53846153846154 7.53846153846154 0,7.69230769230769 7.69230769230769 0,7.84615384615385 7.84615384615385 0,8 8 0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 2,2.15384615384615 2.15384615384615,2.30769230769231 2.30769230769231,2.46153846153846 2.46153846153846,2.61538461538461 2.61538461538461,2.76923076923077 2.76923076923077,2.92307692307692 2.92307692307692,3.07692307692308 3.07692307692308,3.23076923076923 3.23076923076923,3.38461538461538 3.38461538461538,3.53846153846154 3.53846153846154,3.69230769230769 3.69230769230769,3.84615384615385 3.84615384615385,4 4,4.15384615384615 4.15384615384615,4.30769230769231 4.30769230769231,4.46153846153846 4.46153846153846,4.61538461538462 4.61538461538462,4.76923076923077 4.76923076923077,4.92307692307692 4.92307692307692,5.07692307692308 5.07692307692308,5.23076923076923 5.23076923076923,5.38461538461538 5.38461538461538,5.53846153846154 5.53846153846154,5.69230769230769 5.69230769230769,5.84615384615385 5.84615384615385,6.0 6.0,6.15384615384615 6.15384615384615,6.30769230769231 6.30769230769231,6.46153846153846 6.46153846153846,6.61538461538462 6.61538461538462,6.76923076923077 6.76923076923077,6.92307692307692 6.92307692307692,7.07692307692308 7.07692307692308,7.23076923076923 7.23076923076923,7.38461538461539 7.38461538461539,7.53846153846154 7.53846153846154,7.69230769230769 7.69230769230769,7.84615384615385 7.84615384615385,8 8)", + "LINESTRING Z (2 2 0,2.15384615384615 2.15384615384615 0,2.30769230769231 2.30769230769231 0,2.46153846153846 2.46153846153846 0,2.61538461538461 2.61538461538461 0,2.76923076923077 2.76923076923077 0,2.92307692307692 2.92307692307692 0,3.07692307692308 3.07692307692308 0,3.23076923076923 3.23076923076923 0,3.38461538461538 3.38461538461538 0,3.53846153846154 3.53846153846154 0,3.69230769230769 3.69230769230769 0,3.84615384615385 3.84615384615385 0,4 4 0,4.15384615384615 4.15384615384615 0,4.30769230769231 4.30769230769231 0,4.46153846153846 4.46153846153846 0,4.61538461538462 4.61538461538462 0,4.76923076923077 4.76923076923077 0,4.92307692307692 4.92307692307692 0,5.07692307692308 5.07692307692308 0,5.23076923076923 5.23076923076923 0,5.38461538461538 5.38461538461538 0,5.53846153846154 5.53846153846154 0,5.69230769230769 5.69230769230769 0,5.84615384615385 5.84615384615385 0,6.0 6.0 0,6.15384615384615 6.15384615384615 0,6.30769230769231 6.30769230769231 0,6.46153846153846 6.46153846153846 0,6.61538461538462 6.61538461538462 0,6.76923076923077 6.76923076923077 0,6.92307692307692 6.92307692307692 0,7.07692307692308 7.07692307692308 0,7.23076923076923 7.23076923076923 0,7.38461538461539 7.38461538461539 0,7.53846153846154 7.53846153846154 0,7.69230769230769 7.69230769230769 0,7.84615384615385 7.84615384615385 0,8 8 0)", ) # OGRFeature(entities):11 # EntityHandle (String) = 201 - # LINESTRING (8 1,7.62837370825536 0.987348067229724,7.25775889681215 0.975707614760869,6.88916704597178 0.966090122894857,6.52360963603567 0.959507071933107,6.16209814730525 0.956969942177043,5.80564406008193 0.959490213928084,5.45525885466714 0.968079367487651,5.11195401136229 0.983748883157167,4.77674101046882 1.00751024123805,4.45063133228814 1.04037492203173,4.13463645712167 1.08335440583961,3.82976786527082 1.13746017296313,3.53703703703704 1.2037037037037,3.25745545272173 1.28309647836275,2.99203459262631 1.37664997724169,2.74178593705221 1.48537568064195,2.50772096630085 1.61028506886495,2.29085116067365 1.75238962221211,2.09218800047203 1.91270082098484,1.91270082098485 2.09218800047202,1.75238962221211 2.29085116067364,1.61028506886495 2.50772096630085,1.48537568064195 2.74178593705221,1.37664997724169 2.99203459262631,1.28309647836275 3.25745545272172,1.2037037037037 3.53703703703703,1.13746017296313 3.82976786527082,1.08335440583961 4.13463645712166,1.04037492203173 4.45063133228814,1.00751024123805 4.77674101046882,0.983748883157167 5.11195401136229,0.968079367487652 5.45525885466714,0.959490213928084 5.80564406008193,0.956969942177043 6.16209814730525,0.959507071933108 6.52360963603567,0.966090122894857 6.88916704597178,0.975707614760869 7.25775889681216,0.987348067229724 7.62837370825537,1 8) + # LINESTRING Z (8 1 0,7.62837370825536 0.987348067229724 0,7.25775889681215 0.975707614760869 0,6.88916704597178 0.966090122894857 0,6.52360963603567 0.959507071933107 0,6.16209814730525 0.956969942177043 0,5.80564406008193 0.959490213928084 0,5.45525885466714 0.968079367487651 0,5.11195401136229 0.983748883157167 0,4.77674101046882 1.00751024123805 0,4.45063133228814 1.04037492203173 0,4.13463645712167 1.08335440583961 0,3.82976786527082 1.13746017296313 0,3.53703703703704 1.2037037037037 0,3.25745545272173 1.28309647836275 0,2.99203459262631 1.37664997724169 0,2.74178593705221 1.48537568064195 0,2.50772096630085 1.61028506886495 0,2.29085116067365 1.75238962221211 0,2.09218800047203 1.91270082098484 0,1.91270082098485 2.09218800047202 0,1.75238962221211 2.29085116067364 0,1.61028506886495 2.50772096630085 0,1.48537568064195 2.74178593705221 0,1.37664997724169 2.99203459262631 0,1.28309647836275 3.25745545272172 0,1.2037037037037 3.53703703703703 0,1.13746017296313 3.82976786527082 0,1.08335440583961 4.13463645712166 0,1.04037492203173 4.45063133228814 0,1.00751024123805 4.77674101046882 0,0.983748883157167 5.11195401136229 0,0.968079367487652 5.45525885466714 0,0.959490213928084 5.80564406008193 0,0.956969942177043 6.16209814730525 0,0.959507071933108 6.52360963603567 0,0.966090122894857 6.88916704597178 0,0.975707614760869 7.25775889681216 0,0.987348067229724 7.62837370825537 0,1 8 0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (8 1,7.62837370825536 0.987348067229724,7.25775889681215 0.975707614760869,6.88916704597178 0.966090122894857,6.52360963603567 0.959507071933107,6.16209814730525 0.956969942177043,5.80564406008193 0.959490213928084,5.45525885466714 0.968079367487651,5.11195401136229 0.983748883157167,4.77674101046882 1.00751024123805,4.45063133228814 1.04037492203173,4.13463645712167 1.08335440583961,3.82976786527082 1.13746017296313,3.53703703703704 1.2037037037037,3.25745545272173 1.28309647836275,2.99203459262631 1.37664997724169,2.74178593705221 1.48537568064195,2.50772096630085 1.61028506886495,2.29085116067365 1.75238962221211,2.09218800047203 1.91270082098484,1.91270082098485 2.09218800047202,1.75238962221211 2.29085116067364,1.61028506886495 2.50772096630085,1.48537568064195 2.74178593705221,1.37664997724169 2.99203459262631,1.28309647836275 3.25745545272172,1.2037037037037 3.53703703703703,1.13746017296313 3.82976786527082,1.08335440583961 4.13463645712166,1.04037492203173 4.45063133228814,1.00751024123805 4.77674101046882,0.983748883157167 5.11195401136229,0.968079367487652 5.45525885466714,0.959490213928084 5.80564406008193,0.956969942177043 6.16209814730525,0.959507071933108 6.52360963603567,0.966090122894857 6.88916704597178,0.975707614760869 7.25775889681216,0.987348067229724 7.62837370825537,1 8)", + "LINESTRING Z (8 1 0,7.62837370825536 0.987348067229724 0,7.25775889681215 0.975707614760869 0,6.88916704597178 0.966090122894857 0,6.52360963603567 0.959507071933107 0,6.16209814730525 0.956969942177043 0,5.80564406008193 0.959490213928084 0,5.45525885466714 0.968079367487651 0,5.11195401136229 0.983748883157167 0,4.77674101046882 1.00751024123805 0,4.45063133228814 1.04037492203173 0,4.13463645712167 1.08335440583961 0,3.82976786527082 1.13746017296313 0,3.53703703703704 1.2037037037037 0,3.25745545272173 1.28309647836275 0,2.99203459262631 1.37664997724169 0,2.74178593705221 1.48537568064195 0,2.50772096630085 1.61028506886495 0,2.29085116067365 1.75238962221211 0,2.09218800047203 1.91270082098484 0,1.91270082098485 2.09218800047202 0,1.75238962221211 2.29085116067364 0,1.61028506886495 2.50772096630085 0,1.48537568064195 2.74178593705221 0,1.37664997724169 2.99203459262631 0,1.28309647836275 3.25745545272172 0,1.2037037037037 3.53703703703703 0,1.13746017296313 3.82976786527082 0,1.08335440583961 4.13463645712166 0,1.04037492203173 4.45063133228814 0,1.00751024123805 4.77674101046882 0,0.983748883157167 5.11195401136229 0,0.968079367487652 5.45525885466714 0,0.959490213928084 5.80564406008193 0,0.956969942177043 6.16209814730525 0,0.959507071933108 6.52360963603567 0,0.966090122894857 6.88916704597178 0,0.975707614760869 7.25775889681216 0,0.987348067229724 7.62837370825537 0,1 8 0)", ) # OGRFeature(entities):12 @@ -1605,20 +1597,20 @@ def test_ogr_dxf_31(): # OGRFeature(entities):23 # EntityHandle (String) = 212 - # LINESTRING (-2 2,-2.15384615384615 2.15384615384615,-2.30769230769231 2.30769230769231,-2.46153846153846 2.46153846153846,-2.61538461538461 2.61538461538461,-2.76923076923077 2.76923076923077,-2.92307692307692 2.92307692307692,-3.07692307692308 3.07692307692308,-3.23076923076923 3.23076923076923,-3.38461538461538 3.38461538461538,-3.53846153846154 3.53846153846154,-3.69230769230769 3.69230769230769,-3.84615384615385 3.84615384615385,-4 4,-4.15384615384615 4.15384615384615,-4.30769230769231 4.30769230769231,-4.46153846153846 4.46153846153846,-4.61538461538462 4.61538461538462,-4.76923076923077 4.76923076923077,-4.92307692307692 4.92307692307692,-5.07692307692308 5.07692307692308,-5.23076923076923 5.23076923076923,-5.38461538461538 5.38461538461538,-5.53846153846154 5.53846153846154,-5.69230769230769 5.69230769230769,-5.84615384615385 5.84615384615385,-6.0 6.0,-6.15384615384615 6.15384615384615,-6.30769230769231 6.30769230769231,-6.46153846153846 6.46153846153846,-6.61538461538462 6.61538461538462,-6.76923076923077 6.76923076923077,-6.92307692307692 6.92307692307692,-7.07692307692308 7.07692307692308,-7.23076923076923 7.23076923076923,-7.38461538461539 7.38461538461539,-7.53846153846154 7.53846153846154,-7.69230769230769 7.69230769230769,-7.84615384615385 7.84615384615385,-8 8) + # LINESTRING Z (-2 2 -0.0,-2.15384615384615 2.15384615384615 -0.0,-2.30769230769231 2.30769230769231 -0.0,-2.46153846153846 2.46153846153846 -0.0,-2.61538461538461 2.61538461538461 -0.0,-2.76923076923077 2.76923076923077 -0.0,-2.92307692307692 2.92307692307692 -0.0,-3.07692307692308 3.07692307692308 -0.0,-3.23076923076923 3.23076923076923 -0.0,-3.38461538461538 3.38461538461538 -0.0,-3.53846153846154 3.53846153846154 -0.0,-3.69230769230769 3.69230769230769 -0.0,-3.84615384615385 3.84615384615385 -0.0,-4 4 -0.0,-4.15384615384615 4.15384615384615 -0.0,-4.30769230769231 4.30769230769231 -0.0,-4.46153846153846 4.46153846153846 -0.0,-4.61538461538462 4.61538461538462 -0.0,-4.76923076923077 4.76923076923077 -0.0,-4.92307692307692 4.92307692307692 -0.0,-5.07692307692308 5.07692307692308 -0.0,-5.23076923076923 5.23076923076923 -0.0,-5.38461538461538 5.38461538461538 -0.0,-5.53846153846154 5.53846153846154 -0.0,-5.69230769230769 5.69230769230769 -0.0,-5.84615384615385 5.84615384615385 -0.0,-6 6.0 -0.0,-6.15384615384615 6.15384615384615 -0.0,-6.30769230769231 6.30769230769231 -0.0,-6.46153846153846 6.46153846153846 -0.0,-6.61538461538462 6.61538461538462 -0.0,-6.76923076923077 6.76923076923077 -0.0,-6.92307692307692 6.92307692307692 -0.0,-7.07692307692308 7.07692307692308 -0.0,-7.23076923076923 7.23076923076923 -0.0,-7.38461538461539 7.38461538461539 -0.0,-7.53846153846154 7.53846153846154 -0.0,-7.69230769230769 7.69230769230769 -0.0,-7.84615384615385 7.84615384615385 -0.0,-8 8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-2 2,-2.15384615384615 2.15384615384615,-2.30769230769231 2.30769230769231,-2.46153846153846 2.46153846153846,-2.61538461538461 2.61538461538461,-2.76923076923077 2.76923076923077,-2.92307692307692 2.92307692307692,-3.07692307692308 3.07692307692308,-3.23076923076923 3.23076923076923,-3.38461538461538 3.38461538461538,-3.53846153846154 3.53846153846154,-3.69230769230769 3.69230769230769,-3.84615384615385 3.84615384615385,-4 4,-4.15384615384615 4.15384615384615,-4.30769230769231 4.30769230769231,-4.46153846153846 4.46153846153846,-4.61538461538462 4.61538461538462,-4.76923076923077 4.76923076923077,-4.92307692307692 4.92307692307692,-5.07692307692308 5.07692307692308,-5.23076923076923 5.23076923076923,-5.38461538461538 5.38461538461538,-5.53846153846154 5.53846153846154,-5.69230769230769 5.69230769230769,-5.84615384615385 5.84615384615385,-6.0 6.0,-6.15384615384615 6.15384615384615,-6.30769230769231 6.30769230769231,-6.46153846153846 6.46153846153846,-6.61538461538462 6.61538461538462,-6.76923076923077 6.76923076923077,-6.92307692307692 6.92307692307692,-7.07692307692308 7.07692307692308,-7.23076923076923 7.23076923076923,-7.38461538461539 7.38461538461539,-7.53846153846154 7.53846153846154,-7.69230769230769 7.69230769230769,-7.84615384615385 7.84615384615385,-8 8)", + "LINESTRING Z (-2 2 -0.0,-2.15384615384615 2.15384615384615 -0.0,-2.30769230769231 2.30769230769231 -0.0,-2.46153846153846 2.46153846153846 -0.0,-2.61538461538461 2.61538461538461 -0.0,-2.76923076923077 2.76923076923077 -0.0,-2.92307692307692 2.92307692307692 -0.0,-3.07692307692308 3.07692307692308 -0.0,-3.23076923076923 3.23076923076923 -0.0,-3.38461538461538 3.38461538461538 -0.0,-3.53846153846154 3.53846153846154 -0.0,-3.69230769230769 3.69230769230769 -0.0,-3.84615384615385 3.84615384615385 -0.0,-4 4 -0.0,-4.15384615384615 4.15384615384615 -0.0,-4.30769230769231 4.30769230769231 -0.0,-4.46153846153846 4.46153846153846 -0.0,-4.61538461538462 4.61538461538462 -0.0,-4.76923076923077 4.76923076923077 -0.0,-4.92307692307692 4.92307692307692 -0.0,-5.07692307692308 5.07692307692308 -0.0,-5.23076923076923 5.23076923076923 -0.0,-5.38461538461538 5.38461538461538 -0.0,-5.53846153846154 5.53846153846154 -0.0,-5.69230769230769 5.69230769230769 -0.0,-5.84615384615385 5.84615384615385 -0.0,-6 6.0 -0.0,-6.15384615384615 6.15384615384615 -0.0,-6.30769230769231 6.30769230769231 -0.0,-6.46153846153846 6.46153846153846 -0.0,-6.61538461538462 6.61538461538462 -0.0,-6.76923076923077 6.76923076923077 -0.0,-6.92307692307692 6.92307692307692 -0.0,-7.07692307692308 7.07692307692308 -0.0,-7.23076923076923 7.23076923076923 -0.0,-7.38461538461539 7.38461538461539 -0.0,-7.53846153846154 7.53846153846154 -0.0,-7.69230769230769 7.69230769230769 -0.0,-7.84615384615385 7.84615384615385 -0.0,-8 8 -0.0)", ) # OGRFeature(entities):24 # EntityHandle (String) = 213 - # LINESTRING (-8 1,-7.62837370825536 0.987348067229724,-7.25775889681215 0.975707614760869,-6.88916704597178 0.966090122894857,-6.52360963603567 0.959507071933107,-6.16209814730525 0.956969942177043,-5.80564406008193 0.959490213928084,-5.45525885466714 0.968079367487651,-5.11195401136229 0.983748883157167,-4.77674101046882 1.00751024123805,-4.45063133228814 1.04037492203173,-4.13463645712167 1.08335440583961,-3.82976786527082 1.13746017296313,-3.53703703703704 1.2037037037037,-3.25745545272173 1.28309647836275,-2.99203459262631 1.37664997724169,-2.74178593705221 1.48537568064195,-2.50772096630085 1.61028506886495,-2.29085116067365 1.75238962221211,-2.09218800047203 1.91270082098484,-1.91270082098485 2.09218800047202,-1.75238962221211 2.29085116067364,-1.61028506886495 2.50772096630085,-1.48537568064195 2.74178593705221,-1.37664997724169 2.99203459262631,-1.28309647836275 3.25745545272172,-1.2037037037037 3.53703703703703,-1.13746017296313 3.82976786527082,-1.08335440583961 4.13463645712166,-1.04037492203173 4.45063133228814,-1.00751024123805 4.77674101046882,-0.983748883157167 5.11195401136229,-0.968079367487652 5.45525885466714,-0.959490213928084 5.80564406008193,-0.956969942177043 6.16209814730525,-0.959507071933108 6.52360963603567,-0.966090122894857 6.88916704597178,-0.975707614760869 7.25775889681216,-0.987348067229724 7.62837370825537,-1 8) + # LINESTRING Z (-8 1 -0.0,-7.62837370825536 0.987348067229724 -0.0,-7.25775889681215 0.975707614760869 -0.0,-6.88916704597178 0.966090122894857 -0.0,-6.52360963603567 0.959507071933107 -0.0,-6.16209814730525 0.956969942177043 -0.0,-5.80564406008193 0.959490213928084 -0.0,-5.45525885466714 0.968079367487651 -0.0,-5.11195401136229 0.983748883157167 -0.0,-4.77674101046882 1.00751024123805 -0.0,-4.45063133228814 1.04037492203173 -0.0,-4.13463645712167 1.08335440583961 -0.0,-3.82976786527082 1.13746017296313 -0.0,-3.53703703703704 1.2037037037037 -0.0,-3.25745545272173 1.28309647836275 -0.0,-2.99203459262631 1.37664997724169 -0.0,-2.74178593705221 1.48537568064195 -0.0,-2.50772096630085 1.61028506886495 -0.0,-2.29085116067365 1.75238962221211 -0.0,-2.09218800047203 1.91270082098484 -0.0,-1.91270082098485 2.09218800047202 -0.0,-1.75238962221211 2.29085116067364 -0.0,-1.61028506886495 2.50772096630085 -0.0,-1.48537568064195 2.74178593705221 -0.0,-1.37664997724169 2.99203459262631 -0.0,-1.28309647836275 3.25745545272172 -0.0,-1.2037037037037 3.53703703703703 -0.0,-1.13746017296313 3.82976786527082 -0.0,-1.08335440583961 4.13463645712166 -0.0,-1.04037492203173 4.45063133228814 -0.0,-1.00751024123805 4.77674101046882 -0.0,-0.983748883157167 5.11195401136229 -0.0,-0.968079367487652 5.45525885466714 -0.0,-0.959490213928084 5.80564406008193 -0.0,-0.956969942177043 6.16209814730525 -0.0,-0.959507071933108 6.52360963603567 -0.0,-0.966090122894857 6.88916704597178 -0.0,-0.975707614760869 7.25775889681216 -0.0,-0.987348067229724 7.62837370825537 -0.0,-1 8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-8 1,-7.62837370825536 0.987348067229724,-7.25775889681215 0.975707614760869,-6.88916704597178 0.966090122894857,-6.52360963603567 0.959507071933107,-6.16209814730525 0.956969942177043,-5.80564406008193 0.959490213928084,-5.45525885466714 0.968079367487651,-5.11195401136229 0.983748883157167,-4.77674101046882 1.00751024123805,-4.45063133228814 1.04037492203173,-4.13463645712167 1.08335440583961,-3.82976786527082 1.13746017296313,-3.53703703703704 1.2037037037037,-3.25745545272173 1.28309647836275,-2.99203459262631 1.37664997724169,-2.74178593705221 1.48537568064195,-2.50772096630085 1.61028506886495,-2.29085116067365 1.75238962221211,-2.09218800047203 1.91270082098484,-1.91270082098485 2.09218800047202,-1.75238962221211 2.29085116067364,-1.61028506886495 2.50772096630085,-1.48537568064195 2.74178593705221,-1.37664997724169 2.99203459262631,-1.28309647836275 3.25745545272172,-1.2037037037037 3.53703703703703,-1.13746017296313 3.82976786527082,-1.08335440583961 4.13463645712166,-1.04037492203173 4.45063133228814,-1.00751024123805 4.77674101046882,-0.983748883157167 5.11195401136229,-0.968079367487652 5.45525885466714,-0.959490213928084 5.80564406008193,-0.956969942177043 6.16209814730525,-0.959507071933108 6.52360963603567,-0.966090122894857 6.88916704597178,-0.975707614760869 7.25775889681216,-0.987348067229724 7.62837370825537,-1 8)", + "LINESTRING Z (-8 1 -0.0,-7.62837370825536 0.987348067229724 -0.0,-7.25775889681215 0.975707614760869 -0.0,-6.88916704597178 0.966090122894857 -0.0,-6.52360963603567 0.959507071933107 -0.0,-6.16209814730525 0.956969942177043 -0.0,-5.80564406008193 0.959490213928084 -0.0,-5.45525885466714 0.968079367487651 -0.0,-5.11195401136229 0.983748883157167 -0.0,-4.77674101046882 1.00751024123805 -0.0,-4.45063133228814 1.04037492203173 -0.0,-4.13463645712167 1.08335440583961 -0.0,-3.82976786527082 1.13746017296313 -0.0,-3.53703703703704 1.2037037037037 -0.0,-3.25745545272173 1.28309647836275 -0.0,-2.99203459262631 1.37664997724169 -0.0,-2.74178593705221 1.48537568064195 -0.0,-2.50772096630085 1.61028506886495 -0.0,-2.29085116067365 1.75238962221211 -0.0,-2.09218800047203 1.91270082098484 -0.0,-1.91270082098485 2.09218800047202 -0.0,-1.75238962221211 2.29085116067364 -0.0,-1.61028506886495 2.50772096630085 -0.0,-1.48537568064195 2.74178593705221 -0.0,-1.37664997724169 2.99203459262631 -0.0,-1.28309647836275 3.25745545272172 -0.0,-1.2037037037037 3.53703703703703 -0.0,-1.13746017296313 3.82976786527082 -0.0,-1.08335440583961 4.13463645712166 -0.0,-1.04037492203173 4.45063133228814 -0.0,-1.00751024123805 4.77674101046882 -0.0,-0.983748883157167 5.11195401136229 -0.0,-0.968079367487652 5.45525885466714 -0.0,-0.959490213928084 5.80564406008193 -0.0,-0.956969942177043 6.16209814730525 -0.0,-0.959507071933108 6.52360963603567 -0.0,-0.966090122894857 6.88916704597178 -0.0,-0.975707614760869 7.25775889681216 -0.0,-0.987348067229724 7.62837370825537 -0.0,-1 8 -0.0)", ) # OGRFeature(entities):25 @@ -1708,20 +1700,20 @@ def test_ogr_dxf_31(): # OGRFeature(entities):36 # EntityHandle (String) = 224 - # LINESTRING (-2 -2,-2.15384615384615 -2.15384615384615,-2.30769230769231 -2.30769230769231,-2.46153846153846 -2.46153846153846,-2.61538461538461 -2.61538461538461,-2.76923076923077 -2.76923076923077,-2.92307692307692 -2.92307692307692,-3.07692307692308 -3.07692307692308,-3.23076923076923 -3.23076923076923,-3.38461538461538 -3.38461538461538,-3.53846153846154 -3.53846153846154,-3.69230769230769 -3.69230769230769,-3.84615384615385 -3.84615384615385,-4 -4,-4.15384615384615 -4.15384615384615,-4.30769230769231 -4.30769230769231,-4.46153846153846 -4.46153846153846,-4.61538461538462 -4.61538461538462,-4.76923076923077 -4.76923076923077,-4.92307692307692 -4.92307692307692,-5.07692307692308 -5.07692307692308,-5.23076923076923 -5.23076923076923,-5.38461538461538 -5.38461538461538,-5.53846153846154 -5.53846153846154,-5.69230769230769 -5.69230769230769,-5.84615384615385 -5.84615384615385,-6.0 -6.0,-6.15384615384615 -6.15384615384615,-6.30769230769231 -6.30769230769231,-6.46153846153846 -6.46153846153846,-6.61538461538462 -6.61538461538462,-6.76923076923077 -6.76923076923077,-6.92307692307692 -6.92307692307692,-7.07692307692308 -7.07692307692308,-7.23076923076923 -7.23076923076923,-7.38461538461539 -7.38461538461539,-7.53846153846154 -7.53846153846154,-7.69230769230769 -7.69230769230769,-7.84615384615385 -7.84615384615385,-8 -8) + # LINESTRING Z (-2 -2 -0.0,-2.15384615384615 -2.15384615384615 -0.0,-2.30769230769231 -2.30769230769231 -0.0,-2.46153846153846 -2.46153846153846 -0.0,-2.61538461538461 -2.61538461538461 -0.0,-2.76923076923077 -2.76923076923077 -0.0,-2.92307692307692 -2.92307692307692 -0.0,-3.07692307692308 -3.07692307692308 -0.0,-3.23076923076923 -3.23076923076923 -0.0,-3.38461538461538 -3.38461538461538 -0.0,-3.53846153846154 -3.53846153846154 -0.0,-3.69230769230769 -3.69230769230769 -0.0,-3.84615384615385 -3.84615384615385 -0.0,-4 -4 -0.0,-4.15384615384615 -4.15384615384615 -0.0,-4.30769230769231 -4.30769230769231 -0.0,-4.46153846153846 -4.46153846153846 -0.0,-4.61538461538462 -4.61538461538462 -0.0,-4.76923076923077 -4.76923076923077 -0.0,-4.92307692307692 -4.92307692307692 -0.0,-5.07692307692308 -5.07692307692308 -0.0,-5.23076923076923 -5.23076923076923 -0.0,-5.38461538461538 -5.38461538461538 -0.0,-5.53846153846154 -5.53846153846154 -0.0,-5.69230769230769 -5.69230769230769 -0.0,-5.84615384615385 -5.84615384615385 -0.0,-6 -6 -0.0,-6.15384615384615 -6.15384615384615 -0.0,-6.30769230769231 -6.30769230769231 -0.0,-6.46153846153846 -6.46153846153846 -0.0,-6.61538461538462 -6.61538461538462 -0.0,-6.76923076923077 -6.76923076923077 -0.0,-6.92307692307692 -6.92307692307692 -0.0,-7.07692307692308 -7.07692307692308 -0.0,-7.23076923076923 -7.23076923076923 -0.0,-7.38461538461539 -7.38461538461539 -0.0,-7.53846153846154 -7.53846153846154 -0.0,-7.69230769230769 -7.69230769230769 -0.0,-7.84615384615385 -7.84615384615385 -0.0,-8 -8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-2 -2,-2.15384615384615 -2.15384615384615,-2.30769230769231 -2.30769230769231,-2.46153846153846 -2.46153846153846,-2.61538461538461 -2.61538461538461,-2.76923076923077 -2.76923076923077,-2.92307692307692 -2.92307692307692,-3.07692307692308 -3.07692307692308,-3.23076923076923 -3.23076923076923,-3.38461538461538 -3.38461538461538,-3.53846153846154 -3.53846153846154,-3.69230769230769 -3.69230769230769,-3.84615384615385 -3.84615384615385,-4 -4,-4.15384615384615 -4.15384615384615,-4.30769230769231 -4.30769230769231,-4.46153846153846 -4.46153846153846,-4.61538461538462 -4.61538461538462,-4.76923076923077 -4.76923076923077,-4.92307692307692 -4.92307692307692,-5.07692307692308 -5.07692307692308,-5.23076923076923 -5.23076923076923,-5.38461538461538 -5.38461538461538,-5.53846153846154 -5.53846153846154,-5.69230769230769 -5.69230769230769,-5.84615384615385 -5.84615384615385,-6.0 -6.0,-6.15384615384615 -6.15384615384615,-6.30769230769231 -6.30769230769231,-6.46153846153846 -6.46153846153846,-6.61538461538462 -6.61538461538462,-6.76923076923077 -6.76923076923077,-6.92307692307692 -6.92307692307692,-7.07692307692308 -7.07692307692308,-7.23076923076923 -7.23076923076923,-7.38461538461539 -7.38461538461539,-7.53846153846154 -7.53846153846154,-7.69230769230769 -7.69230769230769,-7.84615384615385 -7.84615384615385,-8 -8)", + "LINESTRING Z (-2 -2 -0.0,-2.15384615384615 -2.15384615384615 -0.0,-2.30769230769231 -2.30769230769231 -0.0,-2.46153846153846 -2.46153846153846 -0.0,-2.61538461538461 -2.61538461538461 -0.0,-2.76923076923077 -2.76923076923077 -0.0,-2.92307692307692 -2.92307692307692 -0.0,-3.07692307692308 -3.07692307692308 -0.0,-3.23076923076923 -3.23076923076923 -0.0,-3.38461538461538 -3.38461538461538 -0.0,-3.53846153846154 -3.53846153846154 -0.0,-3.69230769230769 -3.69230769230769 -0.0,-3.84615384615385 -3.84615384615385 -0.0,-4 -4 -0.0,-4.15384615384615 -4.15384615384615 -0.0,-4.30769230769231 -4.30769230769231 -0.0,-4.46153846153846 -4.46153846153846 -0.0,-4.61538461538462 -4.61538461538462 -0.0,-4.76923076923077 -4.76923076923077 -0.0,-4.92307692307692 -4.92307692307692 -0.0,-5.07692307692308 -5.07692307692308 -0.0,-5.23076923076923 -5.23076923076923 -0.0,-5.38461538461538 -5.38461538461538 -0.0,-5.53846153846154 -5.53846153846154 -0.0,-5.69230769230769 -5.69230769230769 -0.0,-5.84615384615385 -5.84615384615385 -0.0,-6 -6 -0.0,-6.15384615384615 -6.15384615384615 -0.0,-6.30769230769231 -6.30769230769231 -0.0,-6.46153846153846 -6.46153846153846 -0.0,-6.61538461538462 -6.61538461538462 -0.0,-6.76923076923077 -6.76923076923077 -0.0,-6.92307692307692 -6.92307692307692 -0.0,-7.07692307692308 -7.07692307692308 -0.0,-7.23076923076923 -7.23076923076923 -0.0,-7.38461538461539 -7.38461538461539 -0.0,-7.53846153846154 -7.53846153846154 -0.0,-7.69230769230769 -7.69230769230769 -0.0,-7.84615384615385 -7.84615384615385 -0.0,-8 -8 -0.0)", ) # OGRFeature(entities):37 # EntityHandle (String) = 225 - # LINESTRING (-8 -1,-7.62837370825536 -0.987348067229724,-7.25775889681215 -0.975707614760869,-6.88916704597178 -0.966090122894857,-6.52360963603567 -0.959507071933107,-6.16209814730525 -0.956969942177043,-5.80564406008193 -0.959490213928084,-5.45525885466714 -0.968079367487651,-5.11195401136229 -0.983748883157167,-4.77674101046882 -1.00751024123805,-4.45063133228814 -1.04037492203173,-4.13463645712167 -1.08335440583961,-3.82976786527082 -1.13746017296313,-3.53703703703704 -1.2037037037037,-3.25745545272173 -1.28309647836275,-2.99203459262631 -1.37664997724169,-2.74178593705221 -1.48537568064195,-2.50772096630085 -1.61028506886495,-2.29085116067365 -1.75238962221211,-2.09218800047203 -1.91270082098484,-1.91270082098485 -2.09218800047202,-1.75238962221211 -2.29085116067364,-1.61028506886495 -2.50772096630085,-1.48537568064195 -2.74178593705221,-1.37664997724169 -2.99203459262631,-1.28309647836275 -3.25745545272172,-1.2037037037037 -3.53703703703703,-1.13746017296313 -3.82976786527082,-1.08335440583961 -4.13463645712166,-1.04037492203173 -4.45063133228814,-1.00751024123805 -4.77674101046882,-0.983748883157167 -5.11195401136229,-0.968079367487652 -5.45525885466714,-0.959490213928084 -5.80564406008193,-0.956969942177043 -6.16209814730525,-0.959507071933108 -6.52360963603567,-0.966090122894857 -6.88916704597178,-0.975707614760869 -7.25775889681216,-0.987348067229724 -7.62837370825537,-1 -8) + # LINESTRING Z (-8 -1 -0.0,-7.62837370825536 -0.987348067229724 -0.0,-7.25775889681215 -0.975707614760869 -0.0,-6.88916704597178 -0.966090122894857 -0.0,-6.52360963603567 -0.959507071933107 -0.0,-6.16209814730525 -0.956969942177043 -0.0,-5.80564406008193 -0.959490213928084 -0.0,-5.45525885466714 -0.968079367487651 -0.0,-5.11195401136229 -0.983748883157167 -0.0,-4.77674101046882 -1.00751024123805 -0.0,-4.45063133228814 -1.04037492203173 -0.0,-4.13463645712167 -1.08335440583961 -0.0,-3.82976786527082 -1.13746017296313 -0.0,-3.53703703703704 -1.2037037037037 -0.0,-3.25745545272173 -1.28309647836275 -0.0,-2.99203459262631 -1.37664997724169 -0.0,-2.74178593705221 -1.48537568064195 -0.0,-2.50772096630085 -1.61028506886495 -0.0,-2.29085116067365 -1.75238962221211 -0.0,-2.09218800047203 -1.91270082098484 -0.0,-1.91270082098485 -2.09218800047202 -0.0,-1.75238962221211 -2.29085116067364 -0.0,-1.61028506886495 -2.50772096630085 -0.0,-1.48537568064195 -2.74178593705221 -0.0,-1.37664997724169 -2.99203459262631 -0.0,-1.28309647836275 -3.25745545272172 -0.0,-1.2037037037037 -3.53703703703703 -0.0,-1.13746017296313 -3.82976786527082 -0.0,-1.08335440583961 -4.13463645712166 -0.0,-1.04037492203173 -4.45063133228814 -0.0,-1.00751024123805 -4.77674101046882 -0.0,-0.983748883157167 -5.11195401136229 -0.0,-0.968079367487652 -5.45525885466714 -0.0,-0.959490213928084 -5.80564406008193 -0.0,-0.956969942177043 -6.16209814730525 -0.0,-0.959507071933108 -6.52360963603567 -0.0,-0.966090122894857 -6.88916704597178 -0.0,-0.975707614760869 -7.25775889681216 -0.0,-0.987348067229724 -7.62837370825537 -0.0,-1 -8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-8 -1,-7.62837370825536 -0.987348067229724,-7.25775889681215 -0.975707614760869,-6.88916704597178 -0.966090122894857,-6.52360963603567 -0.959507071933107,-6.16209814730525 -0.956969942177043,-5.80564406008193 -0.959490213928084,-5.45525885466714 -0.968079367487651,-5.11195401136229 -0.983748883157167,-4.77674101046882 -1.00751024123805,-4.45063133228814 -1.04037492203173,-4.13463645712167 -1.08335440583961,-3.82976786527082 -1.13746017296313,-3.53703703703704 -1.2037037037037,-3.25745545272173 -1.28309647836275,-2.99203459262631 -1.37664997724169,-2.74178593705221 -1.48537568064195,-2.50772096630085 -1.61028506886495,-2.29085116067365 -1.75238962221211,-2.09218800047203 -1.91270082098484,-1.91270082098485 -2.09218800047202,-1.75238962221211 -2.29085116067364,-1.61028506886495 -2.50772096630085,-1.48537568064195 -2.74178593705221,-1.37664997724169 -2.99203459262631,-1.28309647836275 -3.25745545272172,-1.2037037037037 -3.53703703703703,-1.13746017296313 -3.82976786527082,-1.08335440583961 -4.13463645712166,-1.04037492203173 -4.45063133228814,-1.00751024123805 -4.77674101046882,-0.983748883157167 -5.11195401136229,-0.968079367487652 -5.45525885466714,-0.959490213928084 -5.80564406008193,-0.956969942177043 -6.16209814730525,-0.959507071933108 -6.52360963603567,-0.966090122894857 -6.88916704597178,-0.975707614760869 -7.25775889681216,-0.987348067229724 -7.62837370825537,-1 -8)", + "LINESTRING Z (-8 -1 -0.0,-7.62837370825536 -0.987348067229724 -0.0,-7.25775889681215 -0.975707614760869 -0.0,-6.88916704597178 -0.966090122894857 -0.0,-6.52360963603567 -0.959507071933107 -0.0,-6.16209814730525 -0.956969942177043 -0.0,-5.80564406008193 -0.959490213928084 -0.0,-5.45525885466714 -0.968079367487651 -0.0,-5.11195401136229 -0.983748883157167 -0.0,-4.77674101046882 -1.00751024123805 -0.0,-4.45063133228814 -1.04037492203173 -0.0,-4.13463645712167 -1.08335440583961 -0.0,-3.82976786527082 -1.13746017296313 -0.0,-3.53703703703704 -1.2037037037037 -0.0,-3.25745545272173 -1.28309647836275 -0.0,-2.99203459262631 -1.37664997724169 -0.0,-2.74178593705221 -1.48537568064195 -0.0,-2.50772096630085 -1.61028506886495 -0.0,-2.29085116067365 -1.75238962221211 -0.0,-2.09218800047203 -1.91270082098484 -0.0,-1.91270082098485 -2.09218800047202 -0.0,-1.75238962221211 -2.29085116067364 -0.0,-1.61028506886495 -2.50772096630085 -0.0,-1.48537568064195 -2.74178593705221 -0.0,-1.37664997724169 -2.99203459262631 -0.0,-1.28309647836275 -3.25745545272172 -0.0,-1.2037037037037 -3.53703703703703 -0.0,-1.13746017296313 -3.82976786527082 -0.0,-1.08335440583961 -4.13463645712166 -0.0,-1.04037492203173 -4.45063133228814 -0.0,-1.00751024123805 -4.77674101046882 -0.0,-0.983748883157167 -5.11195401136229 -0.0,-0.968079367487652 -5.45525885466714 -0.0,-0.959490213928084 -5.80564406008193 -0.0,-0.956969942177043 -6.16209814730525 -0.0,-0.959507071933108 -6.52360963603567 -0.0,-0.966090122894857 -6.88916704597178 -0.0,-0.975707614760869 -7.25775889681216 -0.0,-0.987348067229724 -7.62837370825537 -0.0,-1 -8 -0.0)", ) # OGRFeature(entities):38 @@ -1818,20 +1810,20 @@ def test_ogr_dxf_31(): # OGRFeature(entities):49 # EntityHandle (String) = 236 - # LINESTRING (2 -2,2.15384615384615 -2.15384615384615,2.30769230769231 -2.30769230769231,2.46153846153846 -2.46153846153846,2.61538461538461 -2.61538461538461,2.76923076923077 -2.76923076923077,2.92307692307692 -2.92307692307692,3.07692307692308 -3.07692307692308,3.23076923076923 -3.23076923076923,3.38461538461538 -3.38461538461538,3.53846153846154 -3.53846153846154,3.69230769230769 -3.69230769230769,3.84615384615385 -3.84615384615385,4 -4,4.15384615384615 -4.15384615384615,4.30769230769231 -4.30769230769231,4.46153846153846 -4.46153846153846,4.61538461538462 -4.61538461538462,4.76923076923077 -4.76923076923077,4.92307692307692 -4.92307692307692,5.07692307692308 -5.07692307692308,5.23076923076923 -5.23076923076923,5.38461538461538 -5.38461538461538,5.53846153846154 -5.53846153846154,5.69230769230769 -5.69230769230769,5.84615384615385 -5.84615384615385,6.0 -6.0,6.15384615384615 -6.15384615384615,6.30769230769231 -6.30769230769231,6.46153846153846 -6.46153846153846,6.61538461538462 -6.61538461538462,6.76923076923077 -6.76923076923077,6.92307692307692 -6.92307692307692,7.07692307692308 -7.07692307692308,7.23076923076923 -7.23076923076923,7.38461538461539 -7.38461538461539,7.53846153846154 -7.53846153846154,7.69230769230769 -7.69230769230769,7.84615384615385 -7.84615384615385,8 -8) + # LINESTRING Z (2 -2 -0.0,2.15384615384615 -2.15384615384615 -0.0,2.30769230769231 -2.30769230769231 -0.0,2.46153846153846 -2.46153846153846 -0.0,2.61538461538461 -2.61538461538461 -0.0,2.76923076923077 -2.76923076923077 -0.0,2.92307692307692 -2.92307692307692 -0.0,3.07692307692308 -3.07692307692308 -0.0,3.23076923076923 -3.23076923076923 -0.0,3.38461538461538 -3.38461538461538 -0.0,3.53846153846154 -3.53846153846154 -0.0,3.69230769230769 -3.69230769230769 -0.0,3.84615384615385 -3.84615384615385 -0.0,4 -4 -0.0,4.15384615384615 -4.15384615384615 -0.0,4.30769230769231 -4.30769230769231 -0.0,4.46153846153846 -4.46153846153846 -0.0,4.61538461538462 -4.61538461538462 -0.0,4.76923076923077 -4.76923076923077 -0.0,4.92307692307692 -4.92307692307692 -0.0,5.07692307692308 -5.07692307692308 -0.0,5.23076923076923 -5.23076923076923 -0.0,5.38461538461538 -5.38461538461538 -0.0,5.53846153846154 -5.53846153846154 -0.0,5.69230769230769 -5.69230769230769 -0.0,5.84615384615385 -5.84615384615385 -0.0,6.0 -6 -0.0,6.15384615384615 -6.15384615384615 -0.0,6.30769230769231 -6.30769230769231 -0.0,6.46153846153846 -6.46153846153846 -0.0,6.61538461538462 -6.61538461538462 -0.0,6.76923076923077 -6.76923076923077 -0.0,6.92307692307692 -6.92307692307692 -0.0,7.07692307692308 -7.07692307692308 -0.0,7.23076923076923 -7.23076923076923 -0.0,7.38461538461539 -7.38461538461539 -0.0,7.53846153846154 -7.53846153846154 -0.0,7.69230769230769 -7.69230769230769 -0.0,7.84615384615385 -7.84615384615385 -0.0,8 -8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 -2,2.15384615384615 -2.15384615384615,2.30769230769231 -2.30769230769231,2.46153846153846 -2.46153846153846,2.61538461538461 -2.61538461538461,2.76923076923077 -2.76923076923077,2.92307692307692 -2.92307692307692,3.07692307692308 -3.07692307692308,3.23076923076923 -3.23076923076923,3.38461538461538 -3.38461538461538,3.53846153846154 -3.53846153846154,3.69230769230769 -3.69230769230769,3.84615384615385 -3.84615384615385,4 -4,4.15384615384615 -4.15384615384615,4.30769230769231 -4.30769230769231,4.46153846153846 -4.46153846153846,4.61538461538462 -4.61538461538462,4.76923076923077 -4.76923076923077,4.92307692307692 -4.92307692307692,5.07692307692308 -5.07692307692308,5.23076923076923 -5.23076923076923,5.38461538461538 -5.38461538461538,5.53846153846154 -5.53846153846154,5.69230769230769 -5.69230769230769,5.84615384615385 -5.84615384615385,6.0 -6.0,6.15384615384615 -6.15384615384615,6.30769230769231 -6.30769230769231,6.46153846153846 -6.46153846153846,6.61538461538462 -6.61538461538462,6.76923076923077 -6.76923076923077,6.92307692307692 -6.92307692307692,7.07692307692308 -7.07692307692308,7.23076923076923 -7.23076923076923,7.38461538461539 -7.38461538461539,7.53846153846154 -7.53846153846154,7.69230769230769 -7.69230769230769,7.84615384615385 -7.84615384615385,8 -8)", + "LINESTRING Z (2 -2 -0.0,2.15384615384615 -2.15384615384615 -0.0,2.30769230769231 -2.30769230769231 -0.0,2.46153846153846 -2.46153846153846 -0.0,2.61538461538461 -2.61538461538461 -0.0,2.76923076923077 -2.76923076923077 -0.0,2.92307692307692 -2.92307692307692 -0.0,3.07692307692308 -3.07692307692308 -0.0,3.23076923076923 -3.23076923076923 -0.0,3.38461538461538 -3.38461538461538 -0.0,3.53846153846154 -3.53846153846154 -0.0,3.69230769230769 -3.69230769230769 -0.0,3.84615384615385 -3.84615384615385 -0.0,4 -4 -0.0,4.15384615384615 -4.15384615384615 -0.0,4.30769230769231 -4.30769230769231 -0.0,4.46153846153846 -4.46153846153846 -0.0,4.61538461538462 -4.61538461538462 -0.0,4.76923076923077 -4.76923076923077 -0.0,4.92307692307692 -4.92307692307692 -0.0,5.07692307692308 -5.07692307692308 -0.0,5.23076923076923 -5.23076923076923 -0.0,5.38461538461538 -5.38461538461538 -0.0,5.53846153846154 -5.53846153846154 -0.0,5.69230769230769 -5.69230769230769 -0.0,5.84615384615385 -5.84615384615385 -0.0,6.0 -6 -0.0,6.15384615384615 -6.15384615384615 -0.0,6.30769230769231 -6.30769230769231 -0.0,6.46153846153846 -6.46153846153846 -0.0,6.61538461538462 -6.61538461538462 -0.0,6.76923076923077 -6.76923076923077 -0.0,6.92307692307692 -6.92307692307692 -0.0,7.07692307692308 -7.07692307692308 -0.0,7.23076923076923 -7.23076923076923 -0.0,7.38461538461539 -7.38461538461539 -0.0,7.53846153846154 -7.53846153846154 -0.0,7.69230769230769 -7.69230769230769 -0.0,7.84615384615385 -7.84615384615385 -0.0,8 -8 -0.0)", ) # OGRFeature(entities):50 # EntityHandle (String) = 237 - # LINESTRING (8 -1,7.62837370825536 -0.987348067229724,7.25775889681215 -0.975707614760869,6.88916704597178 -0.966090122894857,6.52360963603567 -0.959507071933107,6.16209814730525 -0.956969942177043,5.80564406008193 -0.959490213928084,5.45525885466714 -0.968079367487651,5.11195401136229 -0.983748883157167,4.77674101046882 -1.00751024123805,4.45063133228814 -1.04037492203173,4.13463645712167 -1.08335440583961,3.82976786527082 -1.13746017296313,3.53703703703704 -1.2037037037037,3.25745545272173 -1.28309647836275,2.99203459262631 -1.37664997724169,2.74178593705221 -1.48537568064195,2.50772096630085 -1.61028506886495,2.29085116067365 -1.75238962221211,2.09218800047203 -1.91270082098484,1.91270082098485 -2.09218800047202,1.75238962221211 -2.29085116067364,1.61028506886495 -2.50772096630085,1.48537568064195 -2.74178593705221,1.37664997724169 -2.99203459262631,1.28309647836275 -3.25745545272172,1.2037037037037 -3.53703703703703,1.13746017296313 -3.82976786527082,1.08335440583961 -4.13463645712166,1.04037492203173 -4.45063133228814,1.00751024123805 -4.77674101046882,0.983748883157167 -5.11195401136229,0.968079367487652 -5.45525885466714,0.959490213928084 -5.80564406008193,0.956969942177043 -6.16209814730525,0.959507071933108 -6.52360963603567,0.966090122894857 -6.88916704597178,0.975707614760869 -7.25775889681216,0.987348067229724 -7.62837370825537,1 -8) + # LINESTRING Z (8 -1 -0.0,7.62837370825536 -0.987348067229724 -0.0,7.25775889681215 -0.975707614760869 -0.0,6.88916704597178 -0.966090122894857 -0.0,6.52360963603567 -0.959507071933107 -0.0,6.16209814730525 -0.956969942177043 -0.0,5.80564406008193 -0.959490213928084 -0.0,5.45525885466714 -0.968079367487651 -0.0,5.11195401136229 -0.983748883157167 -0.0,4.77674101046882 -1.00751024123805 -0.0,4.45063133228814 -1.04037492203173 -0.0,4.13463645712167 -1.08335440583961 -0.0,3.82976786527082 -1.13746017296313 -0.0,3.53703703703704 -1.2037037037037 -0.0,3.25745545272173 -1.28309647836275 -0.0,2.99203459262631 -1.37664997724169 -0.0,2.74178593705221 -1.48537568064195 -0.0,2.50772096630085 -1.61028506886495 -0.0,2.29085116067365 -1.75238962221211 -0.0,2.09218800047203 -1.91270082098484 -0.0,1.91270082098485 -2.09218800047202 -0.0,1.75238962221211 -2.29085116067364 -0.0,1.61028506886495 -2.50772096630085 -0.0,1.48537568064195 -2.74178593705221 -0.0,1.37664997724169 -2.99203459262631 -0.0,1.28309647836275 -3.25745545272172 -0.0,1.2037037037037 -3.53703703703703 -0.0,1.13746017296313 -3.82976786527082 -0.0,1.08335440583961 -4.13463645712166 -0.0,1.04037492203173 -4.45063133228814 -0.0,1.00751024123805 -4.77674101046882 -0.0,0.983748883157167 -5.11195401136229 -0.0,0.968079367487652 -5.45525885466714 -0.0,0.959490213928084 -5.80564406008193 -0.0,0.956969942177043 -6.16209814730525 -0.0,0.959507071933108 -6.52360963603567 -0.0,0.966090122894857 -6.88916704597178 -0.0,0.975707614760869 -7.25775889681216 -0.0,0.987348067229724 -7.62837370825537 -0.0,1 -8 -0.0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (8 -1,7.62837370825536 -0.987348067229724,7.25775889681215 -0.975707614760869,6.88916704597178 -0.966090122894857,6.52360963603567 -0.959507071933107,6.16209814730525 -0.956969942177043,5.80564406008193 -0.959490213928084,5.45525885466714 -0.968079367487651,5.11195401136229 -0.983748883157167,4.77674101046882 -1.00751024123805,4.45063133228814 -1.04037492203173,4.13463645712167 -1.08335440583961,3.82976786527082 -1.13746017296313,3.53703703703704 -1.2037037037037,3.25745545272173 -1.28309647836275,2.99203459262631 -1.37664997724169,2.74178593705221 -1.48537568064195,2.50772096630085 -1.61028506886495,2.29085116067365 -1.75238962221211,2.09218800047203 -1.91270082098484,1.91270082098485 -2.09218800047202,1.75238962221211 -2.29085116067364,1.61028506886495 -2.50772096630085,1.48537568064195 -2.74178593705221,1.37664997724169 -2.99203459262631,1.28309647836275 -3.25745545272172,1.2037037037037 -3.53703703703703,1.13746017296313 -3.82976786527082,1.08335440583961 -4.13463645712166,1.04037492203173 -4.45063133228814,1.00751024123805 -4.77674101046882,0.983748883157167 -5.11195401136229,0.968079367487652 -5.45525885466714,0.959490213928084 -5.80564406008193,0.956969942177043 -6.16209814730525,0.959507071933108 -6.52360963603567,0.966090122894857 -6.88916704597178,0.975707614760869 -7.25775889681216,0.987348067229724 -7.62837370825537,1 -8)", + "LINESTRING Z (8 -1 -0.0,7.62837370825536 -0.987348067229724 -0.0,7.25775889681215 -0.975707614760869 -0.0,6.88916704597178 -0.966090122894857 -0.0,6.52360963603567 -0.959507071933107 -0.0,6.16209814730525 -0.956969942177043 -0.0,5.80564406008193 -0.959490213928084 -0.0,5.45525885466714 -0.968079367487651 -0.0,5.11195401136229 -0.983748883157167 -0.0,4.77674101046882 -1.00751024123805 -0.0,4.45063133228814 -1.04037492203173 -0.0,4.13463645712167 -1.08335440583961 -0.0,3.82976786527082 -1.13746017296313 -0.0,3.53703703703704 -1.2037037037037 -0.0,3.25745545272173 -1.28309647836275 -0.0,2.99203459262631 -1.37664997724169 -0.0,2.74178593705221 -1.48537568064195 -0.0,2.50772096630085 -1.61028506886495 -0.0,2.29085116067365 -1.75238962221211 -0.0,2.09218800047203 -1.91270082098484 -0.0,1.91270082098485 -2.09218800047202 -0.0,1.75238962221211 -2.29085116067364 -0.0,1.61028506886495 -2.50772096630085 -0.0,1.48537568064195 -2.74178593705221 -0.0,1.37664997724169 -2.99203459262631 -0.0,1.28309647836275 -3.25745545272172 -0.0,1.2037037037037 -3.53703703703703 -0.0,1.13746017296313 -3.82976786527082 -0.0,1.08335440583961 -4.13463645712166 -0.0,1.04037492203173 -4.45063133228814 -0.0,1.00751024123805 -4.77674101046882 -0.0,0.983748883157167 -5.11195401136229 -0.0,0.968079367487652 -5.45525885466714 -0.0,0.959490213928084 -5.80564406008193 -0.0,0.956969942177043 -6.16209814730525 -0.0,0.959507071933108 -6.52360963603567 -0.0,0.966090122894857 -6.88916704597178 -0.0,0.975707614760869 -7.25775889681216 -0.0,0.987348067229724 -7.62837370825537 -0.0,1 -8 -0.0)", ) # OGRFeature(entities):51 @@ -1956,20 +1948,20 @@ def test_ogr_dxf_32(): # OGRFeature(entities):14 # EntityHandle (String) = 1C6 - # LINESTRING (2 2,2.15384615384615 2.15384615384615,2.30769230769231 2.30769230769231,2.46153846153846 2.46153846153846,2.61538461538461 2.61538461538461,2.76923076923077 2.76923076923077,2.92307692307692 2.92307692307692,3.07692307692308 3.07692307692308,3.23076923076923 3.23076923076923,3.38461538461538 3.38461538461538,3.53846153846154 3.53846153846154,3.69230769230769 3.69230769230769,3.84615384615385 3.84615384615385,4 4,4.15384615384615 4.15384615384615,4.30769230769231 4.30769230769231,4.46153846153846 4.46153846153846,4.61538461538462 4.61538461538462,4.76923076923077 4.76923076923077,4.92307692307692 4.92307692307692,5.07692307692308 5.07692307692308,5.23076923076923 5.23076923076923,5.38461538461538 5.38461538461538,5.53846153846154 5.53846153846154,5.69230769230769 5.69230769230769,5.84615384615385 5.84615384615385,6.0 6.0,6.15384615384615 6.15384615384615,6.30769230769231 6.30769230769231,6.46153846153846 6.46153846153846,6.61538461538462 6.61538461538462,6.76923076923077 6.76923076923077,6.92307692307692 6.92307692307692,7.07692307692308 7.07692307692308,7.23076923076923 7.23076923076923,7.38461538461539 7.38461538461539,7.53846153846154 7.53846153846154,7.69230769230769 7.69230769230769,7.84615384615385 7.84615384615385,8 8) + # LINESTRING Z (2 2 0,2.15384615384615 2.15384615384615 0,2.30769230769231 2.30769230769231 0,2.46153846153846 2.46153846153846 0,2.61538461538461 2.61538461538461 0,2.76923076923077 2.76923076923077 0,2.92307692307692 2.92307692307692 0,3.07692307692308 3.07692307692308 0,3.23076923076923 3.23076923076923 0,3.38461538461538 3.38461538461538 0,3.53846153846154 3.53846153846154 0,3.69230769230769 3.69230769230769 0,3.84615384615385 3.84615384615385 0,4 4 0,4.15384615384615 4.15384615384615 0,4.30769230769231 4.30769230769231 0,4.46153846153846 4.46153846153846 0,4.61538461538462 4.61538461538462 0,4.76923076923077 4.76923076923077 0,4.92307692307692 4.92307692307692 0,5.07692307692308 5.07692307692308 0,5.23076923076923 5.23076923076923 0,5.38461538461538 5.38461538461538 0,5.53846153846154 5.53846153846154 0,5.69230769230769 5.69230769230769 0,5.84615384615385 5.84615384615385 0,6.0 6.0 0,6.15384615384615 6.15384615384615 0,6.30769230769231 6.30769230769231 0,6.46153846153846 6.46153846153846 0,6.61538461538462 6.61538461538462 0,6.76923076923077 6.76923076923077 0,6.92307692307692 6.92307692307692 0,7.07692307692308 7.07692307692308 0,7.23076923076923 7.23076923076923 0,7.38461538461539 7.38461538461539 0,7.53846153846154 7.53846153846154 0,7.69230769230769 7.69230769230769 0,7.84615384615385 7.84615384615385 0,8 8 0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2 2,2.15384615384615 2.15384615384615,2.30769230769231 2.30769230769231,2.46153846153846 2.46153846153846,2.61538461538461 2.61538461538461,2.76923076923077 2.76923076923077,2.92307692307692 2.92307692307692,3.07692307692308 3.07692307692308,3.23076923076923 3.23076923076923,3.38461538461538 3.38461538461538,3.53846153846154 3.53846153846154,3.69230769230769 3.69230769230769,3.84615384615385 3.84615384615385,4 4,4.15384615384615 4.15384615384615,4.30769230769231 4.30769230769231,4.46153846153846 4.46153846153846,4.61538461538462 4.61538461538462,4.76923076923077 4.76923076923077,4.92307692307692 4.92307692307692,5.07692307692308 5.07692307692308,5.23076923076923 5.23076923076923,5.38461538461538 5.38461538461538,5.53846153846154 5.53846153846154,5.69230769230769 5.69230769230769,5.84615384615385 5.84615384615385,6.0 6.0,6.15384615384615 6.15384615384615,6.30769230769231 6.30769230769231,6.46153846153846 6.46153846153846,6.61538461538462 6.61538461538462,6.76923076923077 6.76923076923077,6.92307692307692 6.92307692307692,7.07692307692308 7.07692307692308,7.23076923076923 7.23076923076923,7.38461538461539 7.38461538461539,7.53846153846154 7.53846153846154,7.69230769230769 7.69230769230769,7.84615384615385 7.84615384615385,8 8)", + "LINESTRING Z (2 2 0,2.15384615384615 2.15384615384615 0,2.30769230769231 2.30769230769231 0,2.46153846153846 2.46153846153846 0,2.61538461538461 2.61538461538461 0,2.76923076923077 2.76923076923077 0,2.92307692307692 2.92307692307692 0,3.07692307692308 3.07692307692308 0,3.23076923076923 3.23076923076923 0,3.38461538461538 3.38461538461538 0,3.53846153846154 3.53846153846154 0,3.69230769230769 3.69230769230769 0,3.84615384615385 3.84615384615385 0,4 4 0,4.15384615384615 4.15384615384615 0,4.30769230769231 4.30769230769231 0,4.46153846153846 4.46153846153846 0,4.61538461538462 4.61538461538462 0,4.76923076923077 4.76923076923077 0,4.92307692307692 4.92307692307692 0,5.07692307692308 5.07692307692308 0,5.23076923076923 5.23076923076923 0,5.38461538461538 5.38461538461538 0,5.53846153846154 5.53846153846154 0,5.69230769230769 5.69230769230769 0,5.84615384615385 5.84615384615385 0,6.0 6.0 0,6.15384615384615 6.15384615384615 0,6.30769230769231 6.30769230769231 0,6.46153846153846 6.46153846153846 0,6.61538461538462 6.61538461538462 0,6.76923076923077 6.76923076923077 0,6.92307692307692 6.92307692307692 0,7.07692307692308 7.07692307692308 0,7.23076923076923 7.23076923076923 0,7.38461538461539 7.38461538461539 0,7.53846153846154 7.53846153846154 0,7.69230769230769 7.69230769230769 0,7.84615384615385 7.84615384615385 0,8 8 0)", ) # OGRFeature(entities):15 # EntityHandle (String) = 1C7 - # LINESTRING (8 1,7.62837370825536 0.987348067229724,7.25775889681215 0.975707614760869,6.88916704597178 0.966090122894857,6.52360963603567 0.959507071933107,6.16209814730525 0.956969942177043,5.80564406008193 0.959490213928084,5.45525885466714 0.968079367487651,5.11195401136229 0.983748883157167,4.77674101046882 1.00751024123805,4.45063133228814 1.04037492203173,4.13463645712167 1.08335440583961,3.82976786527082 1.13746017296313,3.53703703703704 1.2037037037037,3.25745545272173 1.28309647836275,2.99203459262631 1.37664997724169,2.74178593705221 1.48537568064195,2.50772096630085 1.61028506886495,2.29085116067365 1.75238962221211,2.09218800047203 1.91270082098484,1.91270082098485 2.09218800047202,1.75238962221211 2.29085116067364,1.61028506886495 2.50772096630085,1.48537568064195 2.74178593705221,1.37664997724169 2.99203459262631,1.28309647836275 3.25745545272172,1.2037037037037 3.53703703703703,1.13746017296313 3.82976786527082,1.08335440583961 4.13463645712166,1.04037492203173 4.45063133228814,1.00751024123805 4.77674101046882,0.983748883157167 5.11195401136229,0.968079367487652 5.45525885466714,0.959490213928084 5.80564406008193,0.956969942177043 6.16209814730525,0.959507071933108 6.52360963603567,0.966090122894857 6.88916704597178,0.975707614760869 7.25775889681216,0.987348067229724 7.62837370825537,1 8) + # LINESTRING Z (8 1 0,7.62837370825536 0.987348067229724 0,7.25775889681215 0.975707614760869 0,6.88916704597178 0.966090122894857 0,6.52360963603567 0.959507071933107 0,6.16209814730525 0.956969942177043 0,5.80564406008193 0.959490213928084 0,5.45525885466714 0.968079367487651 0,5.11195401136229 0.983748883157167 0,4.77674101046882 1.00751024123805 0,4.45063133228814 1.04037492203173 0,4.13463645712167 1.08335440583961 0,3.82976786527082 1.13746017296313 0,3.53703703703704 1.2037037037037 0,3.25745545272173 1.28309647836275 0,2.99203459262631 1.37664997724169 0,2.74178593705221 1.48537568064195 0,2.50772096630085 1.61028506886495 0,2.29085116067365 1.75238962221211 0,2.09218800047203 1.91270082098484 0,1.91270082098485 2.09218800047202 0,1.75238962221211 2.29085116067364 0,1.61028506886495 2.50772096630085 0,1.48537568064195 2.74178593705221 0,1.37664997724169 2.99203459262631 0,1.28309647836275 3.25745545272172 0,1.2037037037037 3.53703703703703 0,1.13746017296313 3.82976786527082 0,1.08335440583961 4.13463645712166 0,1.04037492203173 4.45063133228814 0,1.00751024123805 4.77674101046882 0,0.983748883157167 5.11195401136229 0,0.968079367487652 5.45525885466714 0,0.959490213928084 5.80564406008193 0,0.956969942177043 6.16209814730525 0,0.959507071933108 6.52360963603567 0,0.966090122894857 6.88916704597178 0,0.975707614760869 7.25775889681216 0,0.987348067229724 7.62837370825537 0,1 8 0) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (8 1,7.62837370825536 0.987348067229724,7.25775889681215 0.975707614760869,6.88916704597178 0.966090122894857,6.52360963603567 0.959507071933107,6.16209814730525 0.956969942177043,5.80564406008193 0.959490213928084,5.45525885466714 0.968079367487651,5.11195401136229 0.983748883157167,4.77674101046882 1.00751024123805,4.45063133228814 1.04037492203173,4.13463645712167 1.08335440583961,3.82976786527082 1.13746017296313,3.53703703703704 1.2037037037037,3.25745545272173 1.28309647836275,2.99203459262631 1.37664997724169,2.74178593705221 1.48537568064195,2.50772096630085 1.61028506886495,2.29085116067365 1.75238962221211,2.09218800047203 1.91270082098484,1.91270082098485 2.09218800047202,1.75238962221211 2.29085116067364,1.61028506886495 2.50772096630085,1.48537568064195 2.74178593705221,1.37664997724169 2.99203459262631,1.28309647836275 3.25745545272172,1.2037037037037 3.53703703703703,1.13746017296313 3.82976786527082,1.08335440583961 4.13463645712166,1.04037492203173 4.45063133228814,1.00751024123805 4.77674101046882,0.983748883157167 5.11195401136229,0.968079367487652 5.45525885466714,0.959490213928084 5.80564406008193,0.956969942177043 6.16209814730525,0.959507071933108 6.52360963603567,0.966090122894857 6.88916704597178,0.975707614760869 7.25775889681216,0.987348067229724 7.62837370825537,1 8)", + "LINESTRING Z (8 1 0,7.62837370825536 0.987348067229724 0,7.25775889681215 0.975707614760869 0,6.88916704597178 0.966090122894857 0,6.52360963603567 0.959507071933107 0,6.16209814730525 0.956969942177043 0,5.80564406008193 0.959490213928084 0,5.45525885466714 0.968079367487651 0,5.11195401136229 0.983748883157167 0,4.77674101046882 1.00751024123805 0,4.45063133228814 1.04037492203173 0,4.13463645712167 1.08335440583961 0,3.82976786527082 1.13746017296313 0,3.53703703703704 1.2037037037037 0,3.25745545272173 1.28309647836275 0,2.99203459262631 1.37664997724169 0,2.74178593705221 1.48537568064195 0,2.50772096630085 1.61028506886495 0,2.29085116067365 1.75238962221211 0,2.09218800047203 1.91270082098484 0,1.91270082098485 2.09218800047202 0,1.75238962221211 2.29085116067364 0,1.61028506886495 2.50772096630085 0,1.48537568064195 2.74178593705221 0,1.37664997724169 2.99203459262631 0,1.28309647836275 3.25745545272172 0,1.2037037037037 3.53703703703703 0,1.13746017296313 3.82976786527082 0,1.08335440583961 4.13463645712166 0,1.04037492203173 4.45063133228814 0,1.00751024123805 4.77674101046882 0,0.983748883157167 5.11195401136229 0,0.968079367487652 5.45525885466714 0,0.959490213928084 5.80564406008193 0,0.956969942177043 6.16209814730525 0,0.959507071933108 6.52360963603567 0,0.966090122894857 6.88916704597178 0,0.975707614760869 7.25775889681216 0,0.987348067229724 7.62837370825537 0,1 8 0)", ) # OGRFeature(entities):16 @@ -2102,20 +2094,20 @@ def test_ogr_dxf_32(): # OGRFeature(entities):31 # EntityHandle (String) = 1DC - # LINESTRING (-1.0 2.0,-1.07692307692308 2.15384615384615,-1.15384615384615 2.30769230769231,-1.23076923076923 2.46153846153846,-1.30769230769231 2.61538461538461,-1.38461538461538 2.76923076923077,-1.46153846153846 2.92307692307692,-1.53846153846154 3.07692307692308,-1.61538461538461 3.23076923076923,-1.69230769230769 3.38461538461538,-1.76923076923077 3.53846153846154,-1.84615384615384 3.69230769230769,-1.92307692307692 3.84615384615385,-2.0 4.0,-2.07692307692307 4.15384615384615,-2.15384615384615 4.30769230769231,-2.23076923076923 4.46153846153846,-2.30769230769231 4.61538461538462,-2.38461538461538 4.76923076923077,-2.46153846153846 4.92307692307692,-2.53846153846154 5.07692307692308,-2.61538461538461 5.23076923076923,-2.69230769230769 5.38461538461538,-2.76923076923077 5.53846153846154,-2.84615384615384 5.69230769230769,-2.92307692307692 5.84615384615385,-3.0 6.0,-3.07692307692308 6.15384615384615,-3.15384615384615 6.30769230769231,-3.23076923076923 6.46153846153846,-3.30769230769231 6.61538461538462,-3.38461538461538 6.76923076923077,-3.46153846153846 6.92307692307692,-3.53846153846154 7.07692307692308,-3.61538461538461 7.23076923076923,-3.69230769230769 7.38461538461539,-3.76923076923077 7.53846153846154,-3.84615384615384 7.69230769230769,-3.92307692307692 7.84615384615385,-4.0 8.0) + # LINESTRING Z (-1.0 2.0 -1.73205080756888,-1.07692307692308 2.15384615384615 -1.86528548507418,-1.15384615384615 2.30769230769231 -1.99852016257947,-1.23076923076923 2.46153846153846 -2.13175484008477,-1.30769230769231 2.61538461538461 -2.26498951759007,-1.38461538461538 2.76923076923077 -2.39822419509537,-1.46153846153846 2.92307692307692 -2.53145887260067,-1.53846153846154 3.07692307692308 -2.66469355010597,-1.61538461538461 3.23076923076923 -2.79792822761126,-1.69230769230769 3.38461538461538 -2.93116290511656,-1.76923076923077 3.53846153846154 -3.06439758262186,-1.84615384615384 3.69230769230769 -3.19763226012716,-1.92307692307692 3.84615384615385 -3.33086693763246,-2 4.0 -3.46410161513776,-2.07692307692307 4.15384615384615 -3.59733629264305,-2.15384615384615 4.30769230769231 -3.73057097014835,-2.23076923076923 4.46153846153846 -3.86380564765365,-2.30769230769231 4.61538461538462 -3.99704032515895,-2.38461538461538 4.76923076923077 -4.13027500266425,-2.46153846153846 4.92307692307692 -4.26350968016954,-2.53846153846154 5.07692307692308 -4.39674435767484,-2.61538461538461 5.23076923076923 -4.52997903518014,-2.69230769230769 5.38461538461538 -4.66321371268544,-2.76923076923077 5.53846153846154 -4.79644839019074,-2.84615384615384 5.69230769230769 -4.92968306769604,-2.92307692307692 5.84615384615385 -5.06291774520133,-3 6.0 -5.19615242270663,-3.07692307692308 6.15384615384615 -5.32938710021193,-3.15384615384615 6.30769230769231 -5.46262177771723,-3.23076923076923 6.46153846153846 -5.59585645522253,-3.30769230769231 6.61538461538462 -5.72909113272783,-3.38461538461538 6.76923076923077 -5.86232581023313,-3.46153846153846 6.92307692307692 -5.99556048773842,-3.53846153846154 7.07692307692308 -6.12879516524372,-3.61538461538461 7.23076923076923 -6.26202984274902,-3.69230769230769 7.38461538461539 -6.39526452025432,-3.76923076923077 7.53846153846154 -6.52849919775962,-3.84615384615384 7.69230769230769 -6.66173387526491,-3.92307692307692 7.84615384615385 -6.79496855277021,-4 8.0 -6.92820323027551) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-1.0 2.0,-1.07692307692308 2.15384615384615,-1.15384615384615 2.30769230769231,-1.23076923076923 2.46153846153846,-1.30769230769231 2.61538461538461,-1.38461538461538 2.76923076923077,-1.46153846153846 2.92307692307692,-1.53846153846154 3.07692307692308,-1.61538461538461 3.23076923076923,-1.69230769230769 3.38461538461538,-1.76923076923077 3.53846153846154,-1.84615384615384 3.69230769230769,-1.92307692307692 3.84615384615385,-2.0 4.0,-2.07692307692307 4.15384615384615,-2.15384615384615 4.30769230769231,-2.23076923076923 4.46153846153846,-2.30769230769231 4.61538461538462,-2.38461538461538 4.76923076923077,-2.46153846153846 4.92307692307692,-2.53846153846154 5.07692307692308,-2.61538461538461 5.23076923076923,-2.69230769230769 5.38461538461538,-2.76923076923077 5.53846153846154,-2.84615384615384 5.69230769230769,-2.92307692307692 5.84615384615385,-3.0 6.0,-3.07692307692308 6.15384615384615,-3.15384615384615 6.30769230769231,-3.23076923076923 6.46153846153846,-3.30769230769231 6.61538461538462,-3.38461538461538 6.76923076923077,-3.46153846153846 6.92307692307692,-3.53846153846154 7.07692307692308,-3.61538461538461 7.23076923076923,-3.69230769230769 7.38461538461539,-3.76923076923077 7.53846153846154,-3.84615384615384 7.69230769230769,-3.92307692307692 7.84615384615385,-4.0 8.0)", + "LINESTRING Z (-1.0 2.0 -1.73205080756888,-1.07692307692308 2.15384615384615 -1.86528548507418,-1.15384615384615 2.30769230769231 -1.99852016257947,-1.23076923076923 2.46153846153846 -2.13175484008477,-1.30769230769231 2.61538461538461 -2.26498951759007,-1.38461538461538 2.76923076923077 -2.39822419509537,-1.46153846153846 2.92307692307692 -2.53145887260067,-1.53846153846154 3.07692307692308 -2.66469355010597,-1.61538461538461 3.23076923076923 -2.79792822761126,-1.69230769230769 3.38461538461538 -2.93116290511656,-1.76923076923077 3.53846153846154 -3.06439758262186,-1.84615384615384 3.69230769230769 -3.19763226012716,-1.92307692307692 3.84615384615385 -3.33086693763246,-2 4.0 -3.46410161513776,-2.07692307692307 4.15384615384615 -3.59733629264305,-2.15384615384615 4.30769230769231 -3.73057097014835,-2.23076923076923 4.46153846153846 -3.86380564765365,-2.30769230769231 4.61538461538462 -3.99704032515895,-2.38461538461538 4.76923076923077 -4.13027500266425,-2.46153846153846 4.92307692307692 -4.26350968016954,-2.53846153846154 5.07692307692308 -4.39674435767484,-2.61538461538461 5.23076923076923 -4.52997903518014,-2.69230769230769 5.38461538461538 -4.66321371268544,-2.76923076923077 5.53846153846154 -4.79644839019074,-2.84615384615384 5.69230769230769 -4.92968306769604,-2.92307692307692 5.84615384615385 -5.06291774520133,-3 6.0 -5.19615242270663,-3.07692307692308 6.15384615384615 -5.32938710021193,-3.15384615384615 6.30769230769231 -5.46262177771723,-3.23076923076923 6.46153846153846 -5.59585645522253,-3.30769230769231 6.61538461538462 -5.72909113272783,-3.38461538461538 6.76923076923077 -5.86232581023313,-3.46153846153846 6.92307692307692 -5.99556048773842,-3.53846153846154 7.07692307692308 -6.12879516524372,-3.61538461538461 7.23076923076923 -6.26202984274902,-3.69230769230769 7.38461538461539 -6.39526452025432,-3.76923076923077 7.53846153846154 -6.52849919775962,-3.84615384615384 7.69230769230769 -6.66173387526491,-3.92307692307692 7.84615384615385 -6.79496855277021,-4 8.0 -6.92820323027551)", ) # OGRFeature(entities):32 # EntityHandle (String) = 1DD - # LINESTRING (-4.0 1.0,-3.81418685412768 0.987348067229724,-3.62887944840607 0.975707614760869,-3.44458352298589 0.966090122894857,-3.26180481801783 0.959507071933107,-3.08104907365262 0.956969942177043,-2.90282203004096 0.959490213928084,-2.72762942733357 0.968079367487651,-2.55597700568115 0.983748883157167,-2.38837050523441 1.00751024123805,-2.22531566614407 1.04037492203173,-2.06731822856083 1.08335440583961,-1.91488393263541 1.13746017296313,-1.76851851851852 1.2037037037037,-1.62872772636086 1.28309647836275,-1.49601729631315 1.37664997724169,-1.3708929685261 1.48537568064195,-1.25386048315042 1.61028506886495,-1.14542558033682 1.75238962221211,-1.04609400023601 1.91270082098484,-0.956350410492422 2.09218800047202,-0.876194811106054 2.29085116067364,-0.805142534432475 2.50772096630085,-0.742687840320977 2.74178593705221,-0.688324988620847 2.99203459262631,-0.641548239181376 3.25745545272172,-0.601851851851852 3.53703703703703,-0.568730086481566 3.82976786527082,-0.541677202919806 4.13463645712166,-0.520187461015863 4.45063133228814,-0.503755120619026 4.77674101046882,-0.491874441578583 5.11195401136229,-0.484039683743826 5.45525885466714,-0.479745106964042 5.80564406008193,-0.478484971088521 6.16209814730525,-0.479753535966554 6.52360963603567,-0.483045061447428 6.88916704597178,-0.487853807380435 7.25775889681216,-0.493674033614862 7.62837370825537,-0.5 8.0) + # LINESTRING Z (-4 1.0 -6.92820323027551,-3.81418685412768 0.987348067229724 -6.60636542091045,-3.62887944840607 0.975707614760869 -6.28540357918185,-3.44458352298589 0.966090122894857 -5.96619367272616,-3.26180481801783 0.959507071933107 -5.64961166917985,-3.08104907365262 0.956969942177043 -5.33653353617937,-2.90282203004096 0.959490213928084 -5.02783524136118,-2.72762942733357 0.968079367487651 -4.72439275236174,-2.55597700568115 0.983748883157167 -4.42708203681751,-2.38837050523441 1.00751024123805 -4.13677906236495,-2.22531566614407 1.04037492203173 -3.85435979664051,-2.06731822856083 1.08335440583961 -3.58070020728065,-1.91488393263541 1.13746017296313 -3.31667626192183,-1.76851851851852 1.2037037037037 -3.06316392820052,-1.62872772636086 1.28309647836275 -2.82103917375315,-1.49601729631315 1.37664997724169 -2.59117796621621,-1.3708929685261 1.48537568064195 -2.37445627322614,-1.25386048315042 1.61028506886495 -2.1717500624194,-1.14542558033682 1.75238962221211 -1.98393530143245,-1.04609400023601 1.91270082098484 -1.81188795790174,-0.956350410492422 2.09218800047202 -1.65644750081223,-0.876194811106054 2.29085116067364 -1.5176139301639,-0.805142534432475 2.50772096630085 -1.39454777697182,-0.742687840320977 2.74178593705221 -1.28637307359953,-0.688324988620847 2.99203459262631 -1.19221385241058,-0.641548239181376 3.25745545272172 -1.11119414576849,-0.601851851851852 3.53703703703703 -1.04243798603683,-0.568730086481566 3.82976786527082 -0.985069405579114,-0.541677202919806 4.13463645712166 -0.938212436758902,-0.520187461015863 4.45063133228814 -0.90099111193973,-0.503755120619026 4.77674101046882 -0.872529463485141,-0.491874441578583 5.11195401136229 -0.851951523758677,-0.484039683743826 5.45525885466714 -0.838381325123878,-0.479745106964042 5.80564406008193 -0.830942899944286,-0.478484971088521 6.16209814730525 -0.828760280583445,-0.479753535966554 6.52360963603567 -0.830957499404894,-0.483045061447428 6.88916704597178 -0.836658588772177,-0.487853807380435 7.25775889681216 -0.844987581048834,-0.493674033614862 7.62837370825537 -0.855068508598407,-0.5 8.0 -0.866025403784439) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-4.0 1.0,-3.81418685412768 0.987348067229724,-3.62887944840607 0.975707614760869,-3.44458352298589 0.966090122894857,-3.26180481801783 0.959507071933107,-3.08104907365262 0.956969942177043,-2.90282203004096 0.959490213928084,-2.72762942733357 0.968079367487651,-2.55597700568115 0.983748883157167,-2.38837050523441 1.00751024123805,-2.22531566614407 1.04037492203173,-2.06731822856083 1.08335440583961,-1.91488393263541 1.13746017296313,-1.76851851851852 1.2037037037037,-1.62872772636086 1.28309647836275,-1.49601729631315 1.37664997724169,-1.3708929685261 1.48537568064195,-1.25386048315042 1.61028506886495,-1.14542558033682 1.75238962221211,-1.04609400023601 1.91270082098484,-0.956350410492422 2.09218800047202,-0.876194811106054 2.29085116067364,-0.805142534432475 2.50772096630085,-0.742687840320977 2.74178593705221,-0.688324988620847 2.99203459262631,-0.641548239181376 3.25745545272172,-0.601851851851852 3.53703703703703,-0.568730086481566 3.82976786527082,-0.541677202919806 4.13463645712166,-0.520187461015863 4.45063133228814,-0.503755120619026 4.77674101046882,-0.491874441578583 5.11195401136229,-0.484039683743826 5.45525885466714,-0.479745106964042 5.80564406008193,-0.478484971088521 6.16209814730525,-0.479753535966554 6.52360963603567,-0.483045061447428 6.88916704597178,-0.487853807380435 7.25775889681216,-0.493674033614862 7.62837370825537,-0.5 8.0)", + "LINESTRING Z (-4 1.0 -6.92820323027551,-3.81418685412768 0.987348067229724 -6.60636542091045,-3.62887944840607 0.975707614760869 -6.28540357918185,-3.44458352298589 0.966090122894857 -5.96619367272616,-3.26180481801783 0.959507071933107 -5.64961166917985,-3.08104907365262 0.956969942177043 -5.33653353617937,-2.90282203004096 0.959490213928084 -5.02783524136118,-2.72762942733357 0.968079367487651 -4.72439275236174,-2.55597700568115 0.983748883157167 -4.42708203681751,-2.38837050523441 1.00751024123805 -4.13677906236495,-2.22531566614407 1.04037492203173 -3.85435979664051,-2.06731822856083 1.08335440583961 -3.58070020728065,-1.91488393263541 1.13746017296313 -3.31667626192183,-1.76851851851852 1.2037037037037 -3.06316392820052,-1.62872772636086 1.28309647836275 -2.82103917375315,-1.49601729631315 1.37664997724169 -2.59117796621621,-1.3708929685261 1.48537568064195 -2.37445627322614,-1.25386048315042 1.61028506886495 -2.1717500624194,-1.14542558033682 1.75238962221211 -1.98393530143245,-1.04609400023601 1.91270082098484 -1.81188795790174,-0.956350410492422 2.09218800047202 -1.65644750081223,-0.876194811106054 2.29085116067364 -1.5176139301639,-0.805142534432475 2.50772096630085 -1.39454777697182,-0.742687840320977 2.74178593705221 -1.28637307359953,-0.688324988620847 2.99203459262631 -1.19221385241058,-0.641548239181376 3.25745545272172 -1.11119414576849,-0.601851851851852 3.53703703703703 -1.04243798603683,-0.568730086481566 3.82976786527082 -0.985069405579114,-0.541677202919806 4.13463645712166 -0.938212436758902,-0.520187461015863 4.45063133228814 -0.90099111193973,-0.503755120619026 4.77674101046882 -0.872529463485141,-0.491874441578583 5.11195401136229 -0.851951523758677,-0.484039683743826 5.45525885466714 -0.838381325123878,-0.479745106964042 5.80564406008193 -0.830942899944286,-0.478484971088521 6.16209814730525 -0.828760280583445,-0.479753535966554 6.52360963603567 -0.830957499404894,-0.483045061447428 6.88916704597178 -0.836658588772177,-0.487853807380435 7.25775889681216 -0.844987581048834,-0.493674033614862 7.62837370825537 -0.855068508598407,-0.5 8.0 -0.866025403784439)", ) # OGRFeature(entities):33 @@ -2248,20 +2240,20 @@ def test_ogr_dxf_32(): # OGRFeature(entities):48 # EntityHandle (String) = 1F2 - # LINESTRING (0.5 -1.0,0.53846153846154 -1.07692307692308,0.576923076923078 -1.15384615384615,0.615384615384617 -1.23076923076923,0.653846153846155 -1.30769230769231,0.692307692307694 -1.38461538461538,0.730769230769232 -1.46153846153846,0.769230769230771 -1.53846153846154,0.807692307692309 -1.61538461538462,0.846153846153848 -1.69230769230769,0.884615384615386 -1.76923076923077,0.923076923076924 -1.84615384615385,0.961538461538463 -1.92307692307692,1.0 -2.0,1.03846153846154 -2.07692307692308,1.07692307692308 -2.15384615384615,1.11538461538462 -2.23076923076923,1.15384615384616 -2.30769230769231,1.19230769230769 -2.38461538461538,1.23076923076923 -2.46153846153846,1.26923076923077 -2.53846153846154,1.30769230769231 -2.61538461538461,1.34615384615385 -2.69230769230769,1.38461538461539 -2.76923076923077,1.42307692307693 -2.84615384615385,1.46153846153846 -2.92307692307692,1.5 -3.0,1.53846153846154 -3.07692307692308,1.57692307692308 -3.15384615384615,1.61538461538462 -3.23076923076923,1.65384615384616 -3.30769230769231,1.6923076923077 -3.38461538461539,1.73076923076923 -3.46153846153846,1.76923076923077 -3.53846153846154,1.80769230769231 -3.61538461538461,1.84615384615385 -3.69230769230769,1.88461538461539 -3.76923076923077,1.92307692307693 -3.84615384615385,1.96153846153847 -3.92307692307692,2.0 -4.0) + # LINESTRING Z (0.5 -1.0 -2.59807621135332,0.53846153846154 -1.07692307692308 -2.79792822761126,0.576923076923078 -1.15384615384615 -2.99778024386921,0.615384615384617 -1.23076923076923 -3.19763226012716,0.653846153846155 -1.30769230769231 -3.3974842763851,0.692307692307694 -1.38461538461538 -3.59733629264305,0.730769230769232 -1.46153846153846 -3.797188308901,0.769230769230771 -1.53846153846154 -3.99704032515895,0.807692307692309 -1.61538461538462 -4.19689234141689,0.846153846153848 -1.69230769230769 -4.39674435767484,0.884615384615386 -1.76923076923077 -4.59659637393279,0.923076923076924 -1.84615384615385 -4.79644839019073,0.961538461538463 -1.92307692307692 -4.99630040644868,1.0 -2 -5.19615242270663,1.03846153846154 -2.07692307692308 -5.39600443896458,1.07692307692308 -2.15384615384615 -5.59585645522253,1.11538461538462 -2.23076923076923 -5.79570847148047,1.15384615384616 -2.30769230769231 -5.99556048773842,1.19230769230769 -2.38461538461538 -6.19541250399637,1.23076923076923 -2.46153846153846 -6.39526452025432,1.26923076923077 -2.53846153846154 -6.59511653651226,1.30769230769231 -2.61538461538461 -6.79496855277021,1.34615384615385 -2.69230769230769 -6.99482056902816,1.38461538461539 -2.76923076923077 -7.19467258528611,1.42307692307693 -2.84615384615385 -7.39452460154405,1.46153846153846 -2.92307692307692 -7.594376617802,1.5 -3 -7.79422863405995,1.53846153846154 -3.07692307692308 -7.99408065031789,1.57692307692308 -3.15384615384615 -8.19393266657584,1.61538461538462 -3.23076923076923 -8.39378468283379,1.65384615384616 -3.30769230769231 -8.59363669909174,1.6923076923077 -3.38461538461539 -8.79348871534969,1.73076923076923 -3.46153846153846 -8.99334073160763,1.76923076923077 -3.53846153846154 -9.19319274786558,1.80769230769231 -3.61538461538461 -9.39304476412353,1.84615384615385 -3.69230769230769 -9.59289678038147,1.88461538461539 -3.76923076923077 -9.79274879663942,1.92307692307693 -3.84615384615385 -9.99260081289737,1.96153846153847 -3.92307692307692 -10.1924528291553,2.0 -4 -10.3923048454133) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (0.5 -1.0,0.53846153846154 -1.07692307692308,0.576923076923078 -1.15384615384615,0.615384615384617 -1.23076923076923,0.653846153846155 -1.30769230769231,0.692307692307694 -1.38461538461538,0.730769230769232 -1.46153846153846,0.769230769230771 -1.53846153846154,0.807692307692309 -1.61538461538462,0.846153846153848 -1.69230769230769,0.884615384615386 -1.76923076923077,0.923076923076924 -1.84615384615385,0.961538461538463 -1.92307692307692,1.0 -2.0,1.03846153846154 -2.07692307692308,1.07692307692308 -2.15384615384615,1.11538461538462 -2.23076923076923,1.15384615384616 -2.30769230769231,1.19230769230769 -2.38461538461538,1.23076923076923 -2.46153846153846,1.26923076923077 -2.53846153846154,1.30769230769231 -2.61538461538461,1.34615384615385 -2.69230769230769,1.38461538461539 -2.76923076923077,1.42307692307693 -2.84615384615385,1.46153846153846 -2.92307692307692,1.5 -3.0,1.53846153846154 -3.07692307692308,1.57692307692308 -3.15384615384615,1.61538461538462 -3.23076923076923,1.65384615384616 -3.30769230769231,1.6923076923077 -3.38461538461539,1.73076923076923 -3.46153846153846,1.76923076923077 -3.53846153846154,1.80769230769231 -3.61538461538461,1.84615384615385 -3.69230769230769,1.88461538461539 -3.76923076923077,1.92307692307693 -3.84615384615385,1.96153846153847 -3.92307692307692,2.0 -4.0)", + "LINESTRING Z (0.5 -1.0 -2.59807621135332,0.53846153846154 -1.07692307692308 -2.79792822761126,0.576923076923078 -1.15384615384615 -2.99778024386921,0.615384615384617 -1.23076923076923 -3.19763226012716,0.653846153846155 -1.30769230769231 -3.3974842763851,0.692307692307694 -1.38461538461538 -3.59733629264305,0.730769230769232 -1.46153846153846 -3.797188308901,0.769230769230771 -1.53846153846154 -3.99704032515895,0.807692307692309 -1.61538461538462 -4.19689234141689,0.846153846153848 -1.69230769230769 -4.39674435767484,0.884615384615386 -1.76923076923077 -4.59659637393279,0.923076923076924 -1.84615384615385 -4.79644839019073,0.961538461538463 -1.92307692307692 -4.99630040644868,1.0 -2 -5.19615242270663,1.03846153846154 -2.07692307692308 -5.39600443896458,1.07692307692308 -2.15384615384615 -5.59585645522253,1.11538461538462 -2.23076923076923 -5.79570847148047,1.15384615384616 -2.30769230769231 -5.99556048773842,1.19230769230769 -2.38461538461538 -6.19541250399637,1.23076923076923 -2.46153846153846 -6.39526452025432,1.26923076923077 -2.53846153846154 -6.59511653651226,1.30769230769231 -2.61538461538461 -6.79496855277021,1.34615384615385 -2.69230769230769 -6.99482056902816,1.38461538461539 -2.76923076923077 -7.19467258528611,1.42307692307693 -2.84615384615385 -7.39452460154405,1.46153846153846 -2.92307692307692 -7.594376617802,1.5 -3 -7.79422863405995,1.53846153846154 -3.07692307692308 -7.99408065031789,1.57692307692308 -3.15384615384615 -8.19393266657584,1.61538461538462 -3.23076923076923 -8.39378468283379,1.65384615384616 -3.30769230769231 -8.59363669909174,1.6923076923077 -3.38461538461539 -8.79348871534969,1.73076923076923 -3.46153846153846 -8.99334073160763,1.76923076923077 -3.53846153846154 -9.19319274786558,1.80769230769231 -3.61538461538461 -9.39304476412353,1.84615384615385 -3.69230769230769 -9.59289678038147,1.88461538461539 -3.76923076923077 -9.79274879663942,1.92307692307693 -3.84615384615385 -9.99260081289737,1.96153846153847 -3.92307692307692 -10.1924528291553,2.0 -4 -10.3923048454133)", ) # OGRFeature(entities):49 # EntityHandle (String) = 1F3 - # LINESTRING (-3.25 -0.5,-3.07367580370539 -0.493674033614862,-2.89709873733542 -0.487853807380434,-2.72001593081474 -0.483045061447428,-2.542174514068 -0.479753535966554,-2.36332161701984 -0.478484971088521,-2.1832043695949 -0.479745106964042,-2.00156990171783 -0.484039683743825,-1.81816534331327 -0.491874441578583,-1.63273782430587 -0.503755120619026,-1.44503447462027 -0.520187461015863,-1.25480242418112 -0.541677202919806,-1.06178880291306 -0.568730086481565,-0.865740740740739 -0.601851851851852,-0.666405367588798 -0.641548239181375,-0.463529813381883 -0.688324988620846,-0.256861208044639 -0.742687840320976,-0.04614668150171 -0.805142534432475,0.168866636322258 -0.876194811106053,0.388431615502622 -0.956350410492422,0.612790589861596 -1.04609400023601,0.841943559399181 -1.14542558033682,1.07564819029316 -1.25386048315042,1.31365161246818 -1.3708929685261,1.55570095584888 -1.49601729631315,1.80154335035992 -1.62872772636086,2.05092592592592 -1.76851851851852,2.30359581247155 -1.91488393263541,2.55930013992144 -2.06731822856083,2.81778603820024 -2.22531566614407,3.07880063723259 -2.38837050523441,3.34209106694314 -2.55597700568115,3.60740445725653 -2.72762942733357,3.87448793809741 -2.90282203004097,4.14308863939042 -3.08104907365262,4.4129536910602 -3.26180481801784,4.68383022303141 -3.44458352298589,4.95546536522868 -3.62887944840608,5.22760624757667 -3.81418685412768,5.5 -4.0) + # LINESTRING Z (-3.25 -0.5 -7.36121593216773,-3.07367580370539 -0.493674033614862 -7.03389967520965,-2.89709873733542 -0.487853807380434 -6.70789736970626,-2.72001593081474 -0.483045061447428 -6.38452296711225,-2.542174514068 -0.479753535966554 -6.06509041888229,-2.36332161701984 -0.478484971088521 -5.75091367647109,-2.1832043695949 -0.479745106964042 -5.44330669133333,-2.00156990171783 -0.484039683743825 -5.14358341492368,-1.81816534331327 -0.491874441578583 -4.85305779869685,-1.63273782430587 -0.503755120619026 -4.57304379410752,-1.44503447462027 -0.520187461015863 -4.30485535261037,-1.25480242418112 -0.541677202919806 -4.0498064256601,-1.06178880291306 -0.568730086481565 -3.80921096471139,-0.865740740740739 -0.601851851851852 -3.58438292121893,-0.666405367588798 -0.641548239181375 -3.3766362466374,-0.463529813381883 -0.688324988620846 -3.1872848924215,-0.256861208044639 -0.742687840320976 -3.0176428100259,-0.04614668150171 -0.805142534432475 -2.86902395090531,0.168866636322258 -0.876194811106053 -2.74274226651439,0.388431615502622 -0.956350410492422 -2.64011170830786,0.612790589861596 -1.04609400023601 -2.5623914797631,0.841943559399181 -1.14542558033682 -2.50958158088012,1.07564819029316 -1.25386048315042 -2.48042280818152,1.31365161246818 -1.3708929685261 -2.4736012102126,1.55570095584888 -1.49601729631315 -2.48780283551868,1.80154335035992 -1.62872772636086 -2.52171373264507,2.05092592592592 -1.76851851851852 -2.57401995013708,2.30359581247155 -1.91488393263541 -2.64340753654003,2.55930013992144 -2.06731822856083 -2.72856254039923,2.81778603820024 -2.22531566614407 -2.82817101025998,3.07880063723259 -2.38837050523441 -2.94091899466761,3.34209106694314 -2.55597700568115 -3.06549254216743,3.60740445725653 -2.72762942733357 -3.20057770130475,3.87448793809741 -2.90282203004097 -3.34486052062488,4.14308863939042 -3.08104907365262 -3.49702704867313,4.4129536910602 -3.26180481801784 -3.65576333399482,4.68383022303141 -3.44458352298589 -3.81975542513526,4.95546536522868 -3.62887944840608 -3.98768937063976,5.22760624757667 -3.81418685412768 -4.15825121905363,5.5 -4 -4.33012701892219) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (-3.25 -0.5,-3.07367580370539 -0.493674033614862,-2.89709873733542 -0.487853807380434,-2.72001593081474 -0.483045061447428,-2.542174514068 -0.479753535966554,-2.36332161701984 -0.478484971088521,-2.1832043695949 -0.479745106964042,-2.00156990171783 -0.484039683743825,-1.81816534331327 -0.491874441578583,-1.63273782430587 -0.503755120619026,-1.44503447462027 -0.520187461015863,-1.25480242418112 -0.541677202919806,-1.06178880291306 -0.568730086481565,-0.865740740740739 -0.601851851851852,-0.666405367588798 -0.641548239181375,-0.463529813381883 -0.688324988620846,-0.256861208044639 -0.742687840320976,-0.04614668150171 -0.805142534432475,0.168866636322258 -0.876194811106053,0.388431615502622 -0.956350410492422,0.612790589861596 -1.04609400023601,0.841943559399181 -1.14542558033682,1.07564819029316 -1.25386048315042,1.31365161246818 -1.3708929685261,1.55570095584888 -1.49601729631315,1.80154335035992 -1.62872772636086,2.05092592592592 -1.76851851851852,2.30359581247155 -1.91488393263541,2.55930013992144 -2.06731822856083,2.81778603820024 -2.22531566614407,3.07880063723259 -2.38837050523441,3.34209106694314 -2.55597700568115,3.60740445725653 -2.72762942733357,3.87448793809741 -2.90282203004097,4.14308863939042 -3.08104907365262,4.4129536910602 -3.26180481801784,4.68383022303141 -3.44458352298589,4.95546536522868 -3.62887944840608,5.22760624757667 -3.81418685412768,5.5 -4.0)", + "LINESTRING Z (-3.25 -0.5 -7.36121593216773,-3.07367580370539 -0.493674033614862 -7.03389967520965,-2.89709873733542 -0.487853807380434 -6.70789736970626,-2.72001593081474 -0.483045061447428 -6.38452296711225,-2.542174514068 -0.479753535966554 -6.06509041888229,-2.36332161701984 -0.478484971088521 -5.75091367647109,-2.1832043695949 -0.479745106964042 -5.44330669133333,-2.00156990171783 -0.484039683743825 -5.14358341492368,-1.81816534331327 -0.491874441578583 -4.85305779869685,-1.63273782430587 -0.503755120619026 -4.57304379410752,-1.44503447462027 -0.520187461015863 -4.30485535261037,-1.25480242418112 -0.541677202919806 -4.0498064256601,-1.06178880291306 -0.568730086481565 -3.80921096471139,-0.865740740740739 -0.601851851851852 -3.58438292121893,-0.666405367588798 -0.641548239181375 -3.3766362466374,-0.463529813381883 -0.688324988620846 -3.1872848924215,-0.256861208044639 -0.742687840320976 -3.0176428100259,-0.04614668150171 -0.805142534432475 -2.86902395090531,0.168866636322258 -0.876194811106053 -2.74274226651439,0.388431615502622 -0.956350410492422 -2.64011170830786,0.612790589861596 -1.04609400023601 -2.5623914797631,0.841943559399181 -1.14542558033682 -2.50958158088012,1.07564819029316 -1.25386048315042 -2.48042280818152,1.31365161246818 -1.3708929685261 -2.4736012102126,1.55570095584888 -1.49601729631315 -2.48780283551868,1.80154335035992 -1.62872772636086 -2.52171373264507,2.05092592592592 -1.76851851851852 -2.57401995013708,2.30359581247155 -1.91488393263541 -2.64340753654003,2.55930013992144 -2.06731822856083 -2.72856254039923,2.81778603820024 -2.22531566614407 -2.82817101025998,3.07880063723259 -2.38837050523441 -2.94091899466761,3.34209106694314 -2.55597700568115 -3.06549254216743,3.60740445725653 -2.72762942733357 -3.20057770130475,3.87448793809741 -2.90282203004097 -3.34486052062488,4.14308863939042 -3.08104907365262 -3.49702704867313,4.4129536910602 -3.26180481801784 -3.65576333399482,4.68383022303141 -3.44458352298589 -3.81975542513526,4.95546536522868 -3.62887944840608 -3.98768937063976,5.22760624757667 -3.81418685412768 -4.15825121905363,5.5 -4 -4.33012701892219)", ) # OGRFeature(entities):50 @@ -2394,20 +2386,20 @@ def test_ogr_dxf_32(): # OGRFeature(entities):65 # EntityHandle (String) = 208 - # LINESTRING (2.75 0.5,2.96153846153846 0.538461538461539,3.17307692307692 0.576923076923077,3.38461538461539 0.615384615384616,3.59615384615385 0.653846153846154,3.80769230769231 0.692307692307693,4.01923076923077 0.730769230769231,4.23076923076923 0.76923076923077,4.44230769230769 0.807692307692308,4.65384615384616 0.846153846153847,4.86538461538462 0.884615384615385,5.07692307692308 0.923076923076924,5.28846153846154 0.961538461538462,5.5 1.0,5.71153846153846 1.03846153846154,5.92307692307693 1.07692307692308,6.13461538461539 1.11538461538462,6.34615384615385 1.15384615384615,6.55769230769231 1.19230769230769,6.76923076923077 1.23076923076923,6.98076923076923 1.26923076923077,7.19230769230769 1.30769230769231,7.40384615384616 1.34615384615385,7.61538461538462 1.38461538461539,7.82692307692308 1.42307692307692,8.03846153846154 1.46153846153846,8.25 1.5,8.46153846153846 1.53846153846154,8.67307692307693 1.57692307692308,8.88461538461539 1.61538461538462,9.09615384615385 1.65384615384615,9.30769230769231 1.69230769230769,9.51923076923077 1.73076923076923,9.73076923076923 1.76923076923077,9.94230769230769 1.80769230769231,10.1538461538462 1.84615384615385,10.3653846153846 1.88461538461539,10.5769230769231 1.92307692307692,10.7884615384615 1.96153846153846,11.0 2.0) + # LINESTRING Z (2.75 0.5 -0.43301270189222,2.96153846153846 0.538461538461539 -0.466321371268544,3.17307692307692 0.576923076923077 -0.499630040644869,3.38461538461539 0.615384615384616 -0.532938710021194,3.59615384615385 0.653846153846154 -0.566247379397518,3.80769230769231 0.692307692307693 -0.599556048773843,4.01923076923077 0.730769230769231 -0.632864718150167,4.23076923076923 0.76923076923077 -0.666173387526492,4.44230769230769 0.807692307692308 -0.699482056902817,4.65384615384616 0.846153846153847 -0.732790726279141,4.86538461538462 0.884615384615385 -0.766099395655466,5.07692307692308 0.923076923076924 -0.79940806503179,5.28846153846154 0.961538461538462 -0.832716734408115,5.5 1.0 -0.866025403784439,5.71153846153846 1.03846153846154 -0.899334073160764,5.92307692307693 1.07692307692308 -0.932642742537089,6.13461538461539 1.11538461538462 -0.965951411913413,6.34615384615385 1.15384615384615 -0.999260081289738,6.55769230769231 1.19230769230769 -1.03256875066606,6.76923076923077 1.23076923076923 -1.06587742004239,6.98076923076923 1.26923076923077 -1.09918608941871,7.19230769230769 1.30769230769231 -1.13249475879504,7.40384615384616 1.34615384615385 -1.16580342817136,7.61538461538462 1.38461538461539 -1.19911209754769,7.82692307692308 1.42307692307692 -1.23242076692401,8.03846153846154 1.46153846153846 -1.26572943630033,8.25 1.5 -1.29903810567666,8.46153846153846 1.53846153846154 -1.33234677505298,8.67307692307693 1.57692307692308 -1.36565544442931,8.88461538461539 1.61538461538462 -1.39896411380563,9.09615384615385 1.65384615384615 -1.43227278318196,9.30769230769231 1.69230769230769 -1.46558145255828,9.51923076923077 1.73076923076923 -1.49889012193461,9.73076923076923 1.76923076923077 -1.53219879131093,9.94230769230769 1.80769230769231 -1.56550746068726,10.1538461538462 1.84615384615385 -1.59881613006358,10.3653846153846 1.88461538461539 -1.6321247994399,10.5769230769231 1.92307692307692 -1.66543346881623,10.7884615384615 1.96153846153846 -1.69874213819255,11.0 2.0 -1.73205080756888) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (2.75 0.5,2.96153846153846 0.538461538461539,3.17307692307692 0.576923076923077,3.38461538461539 0.615384615384616,3.59615384615385 0.653846153846154,3.80769230769231 0.692307692307693,4.01923076923077 0.730769230769231,4.23076923076923 0.76923076923077,4.44230769230769 0.807692307692308,4.65384615384616 0.846153846153847,4.86538461538462 0.884615384615385,5.07692307692308 0.923076923076924,5.28846153846154 0.961538461538462,5.5 1.0,5.71153846153846 1.03846153846154,5.92307692307693 1.07692307692308,6.13461538461539 1.11538461538462,6.34615384615385 1.15384615384615,6.55769230769231 1.19230769230769,6.76923076923077 1.23076923076923,6.98076923076923 1.26923076923077,7.19230769230769 1.30769230769231,7.40384615384616 1.34615384615385,7.61538461538462 1.38461538461539,7.82692307692308 1.42307692307692,8.03846153846154 1.46153846153846,8.25 1.5,8.46153846153846 1.53846153846154,8.67307692307693 1.57692307692308,8.88461538461539 1.61538461538462,9.09615384615385 1.65384615384615,9.30769230769231 1.69230769230769,9.51923076923077 1.73076923076923,9.73076923076923 1.76923076923077,9.94230769230769 1.80769230769231,10.1538461538462 1.84615384615385,10.3653846153846 1.88461538461539,10.5769230769231 1.92307692307692,10.7884615384615 1.96153846153846,11.0 2.0)", + "LINESTRING Z (2.75 0.5 -0.43301270189222,2.96153846153846 0.538461538461539 -0.466321371268544,3.17307692307692 0.576923076923077 -0.499630040644869,3.38461538461539 0.615384615384616 -0.532938710021194,3.59615384615385 0.653846153846154 -0.566247379397518,3.80769230769231 0.692307692307693 -0.599556048773843,4.01923076923077 0.730769230769231 -0.632864718150167,4.23076923076923 0.76923076923077 -0.666173387526492,4.44230769230769 0.807692307692308 -0.699482056902817,4.65384615384616 0.846153846153847 -0.732790726279141,4.86538461538462 0.884615384615385 -0.766099395655466,5.07692307692308 0.923076923076924 -0.79940806503179,5.28846153846154 0.961538461538462 -0.832716734408115,5.5 1.0 -0.866025403784439,5.71153846153846 1.03846153846154 -0.899334073160764,5.92307692307693 1.07692307692308 -0.932642742537089,6.13461538461539 1.11538461538462 -0.965951411913413,6.34615384615385 1.15384615384615 -0.999260081289738,6.55769230769231 1.19230769230769 -1.03256875066606,6.76923076923077 1.23076923076923 -1.06587742004239,6.98076923076923 1.26923076923077 -1.09918608941871,7.19230769230769 1.30769230769231 -1.13249475879504,7.40384615384616 1.34615384615385 -1.16580342817136,7.61538461538462 1.38461538461539 -1.19911209754769,7.82692307692308 1.42307692307692 -1.23242076692401,8.03846153846154 1.46153846153846 -1.26572943630033,8.25 1.5 -1.29903810567666,8.46153846153846 1.53846153846154 -1.33234677505298,8.67307692307693 1.57692307692308 -1.36565544442931,8.88461538461539 1.61538461538462 -1.39896411380563,9.09615384615385 1.65384615384615 -1.43227278318196,9.30769230769231 1.69230769230769 -1.46558145255828,9.51923076923077 1.73076923076923 -1.49889012193461,9.73076923076923 1.76923076923077 -1.53219879131093,9.94230769230769 1.80769230769231 -1.56550746068726,10.1538461538462 1.84615384615385 -1.59881613006358,10.3653846153846 1.88461538461539 -1.6321247994399,10.5769230769231 1.92307692307692 -1.66543346881623,10.7884615384615 1.96153846153846 -1.69874213819255,11.0 2.0 -1.73205080756888)", ) # OGRFeature(entities):66 # EntityHandle (String) = 209 - # LINESTRING (5.75 5.5,5.5082446180819 5.22760624757667,5.26788002157825 4.95546536522868,5.03029699590351 4.68383022303141,4.79688632647213 4.4129536910602,4.56903879869856 4.14308863939042,4.34814519799727 3.87448793809741,4.1355963097827 3.60740445725653,3.93278291946931 3.34209106694314,3.74109581247155 3.07880063723259,3.56192577420388 2.81778603820024,3.39666359008075 2.55930013992144,3.24670004551661 2.30359581247155,3.11342592592593 2.05092592592593,2.99823201672314 1.80154335035992,2.90250910332271 1.55570095584889,2.8276479711391 1.31365161246818,2.77503940558674 1.07564819029316,2.74607419208011 0.84194355939918,2.74214311603365 0.612790589861594,2.76457901346955 0.38843161550262,2.8133818843878 0.168866636322256,2.88721889276623 -0.046146681501713,2.98469925319038 -0.256861208044643,3.10443218024579 -0.463529813381887,3.24502688851802 -0.666405367588803,3.4050925925926 -0.865740740740744,3.58323850705508 -1.06178880291307,3.77807384649101 -1.25480242418113,3.98820782548594 -1.44503447462028,4.21224965862541 -1.63273782430588,4.44880856049496 -1.81816534331328,4.69649374568015 -2.00156990171784,4.95391442876651 -2.18320436959491,5.2196798243396 -2.36332161701985,5.49239914698496 -2.54217451406801,5.77068161128813 -2.72001593081475,6.05313643183467 -2.89709873733543,6.33837282321012 -3.0736758037054,6.625 -3.25) + # LINESTRING Z (5.75 5.50000000000001 1.29903810567666,5.5082446180819 5.22760624757667 1.22405710092841,5.26788002157825 4.95546536522868 1.14885710427104,5.03029699590351 4.68383022303141 1.07321912379545,4.79688632647213 4.4129536910602 0.996924167592515,4.56903879869856 4.14308863939042 0.91975324375312,4.34814519799727 3.87448793809741 0.841487360368152,4.1355963097827 3.60740445725653 0.761907525528497,3.93278291946931 3.34209106694314 0.68079474732504,3.74109581247155 3.07880063723259 0.597930033848667,3.56192577420388 2.81778603820024 0.513094393190262,3.39666359008075 2.55930013992144 0.426068833440712,3.24670004551661 2.30359581247155 0.336634362690902,3.11342592592593 2.05092592592593 0.244571989031716,2.99823201672314 1.80154335035992 0.149662720554042,2.90250910332271 1.55570095584889 0.051687565348764,2.8276479711391 1.31365161246818 -0.049572468493233,2.77503940558674 1.07564819029316 -0.154336372881063,2.74607419208011 0.84194355939918 -0.26282313972384,2.74214311603365 0.612790589861594 -0.375251760930679,2.76457901346955 0.38843161550262 -0.491832103747815,2.8133818843878 0.168866636322256 -0.612564168175248,2.88721889276623 -0.046146681501713 -0.737238086966744,2.98469925319038 -0.256861208044643 -0.865634868213187,3.10443218024579 -0.463529813381887 -0.997535520005462,3.24502688851802 -0.666405367588803 -1.13272105043446,3.4050925925926 -0.865740740740744 -1.27097246759105,3.58323850705508 -1.06178880291307 -1.41207077956614,3.77807384649101 -1.25480242418113 -1.5557969944506,3.98820782548594 -1.44503447462028 -1.70193212033533,4.21224965862541 -1.63273782430588 -1.85025716531119,4.44880856049496 -1.81816534331328 -2.00055313746909,4.69649374568015 -2.00156990171784 -2.15260104489991,4.95391442876651 -2.18320436959491 -2.30618189569452,5.2196798243396 -2.36332161701985 -2.46107669794383,5.49239914698496 -2.54217451406801 -2.61706645973871,5.77068161128813 -2.72001593081475 -2.77393218917004,6.05313643183467 -2.89709873733543 -2.93145489432872,6.33837282321012 -3.0736758037054 -3.08941558330563,6.625 -3.25 -3.24759526419165) feat = lyr.GetNextFeature() ogrtest.check_feature_geometry( feat, - "LINESTRING (5.75 5.5,5.5082446180819 5.22760624757667,5.26788002157825 4.95546536522868,5.03029699590351 4.68383022303141,4.79688632647213 4.4129536910602,4.56903879869856 4.14308863939042,4.34814519799727 3.87448793809741,4.1355963097827 3.60740445725653,3.93278291946931 3.34209106694314,3.74109581247155 3.07880063723259,3.56192577420388 2.81778603820024,3.39666359008075 2.55930013992144,3.24670004551661 2.30359581247155,3.11342592592593 2.05092592592593,2.99823201672314 1.80154335035992,2.90250910332271 1.55570095584889,2.8276479711391 1.31365161246818,2.77503940558674 1.07564819029316,2.74607419208011 0.84194355939918,2.74214311603365 0.612790589861594,2.76457901346955 0.38843161550262,2.8133818843878 0.168866636322256,2.88721889276623 -0.046146681501713,2.98469925319038 -0.256861208044643,3.10443218024579 -0.463529813381887,3.24502688851802 -0.666405367588803,3.4050925925926 -0.865740740740744,3.58323850705508 -1.06178880291307,3.77807384649101 -1.25480242418113,3.98820782548594 -1.44503447462028,4.21224965862541 -1.63273782430588,4.44880856049496 -1.81816534331328,4.69649374568015 -2.00156990171784,4.95391442876651 -2.18320436959491,5.2196798243396 -2.36332161701985,5.49239914698496 -2.54217451406801,5.77068161128813 -2.72001593081475,6.05313643183467 -2.89709873733543,6.33837282321012 -3.0736758037054,6.625 -3.25)", + "LINESTRING Z (5.75 5.50000000000001 1.29903810567666,5.5082446180819 5.22760624757667 1.22405710092841,5.26788002157825 4.95546536522868 1.14885710427104,5.03029699590351 4.68383022303141 1.07321912379545,4.79688632647213 4.4129536910602 0.996924167592515,4.56903879869856 4.14308863939042 0.91975324375312,4.34814519799727 3.87448793809741 0.841487360368152,4.1355963097827 3.60740445725653 0.761907525528497,3.93278291946931 3.34209106694314 0.68079474732504,3.74109581247155 3.07880063723259 0.597930033848667,3.56192577420388 2.81778603820024 0.513094393190262,3.39666359008075 2.55930013992144 0.426068833440712,3.24670004551661 2.30359581247155 0.336634362690902,3.11342592592593 2.05092592592593 0.244571989031716,2.99823201672314 1.80154335035992 0.149662720554042,2.90250910332271 1.55570095584889 0.051687565348764,2.8276479711391 1.31365161246818 -0.049572468493233,2.77503940558674 1.07564819029316 -0.154336372881063,2.74607419208011 0.84194355939918 -0.26282313972384,2.74214311603365 0.612790589861594 -0.375251760930679,2.76457901346955 0.38843161550262 -0.491832103747815,2.8133818843878 0.168866636322256 -0.612564168175248,2.88721889276623 -0.046146681501713 -0.737238086966744,2.98469925319038 -0.256861208044643 -0.865634868213187,3.10443218024579 -0.463529813381887 -0.997535520005462,3.24502688851802 -0.666405367588803 -1.13272105043446,3.4050925925926 -0.865740740740744 -1.27097246759105,3.58323850705508 -1.06178880291307 -1.41207077956614,3.77807384649101 -1.25480242418113 -1.5557969944506,3.98820782548594 -1.44503447462028 -1.70193212033533,4.21224965862541 -1.63273782430588 -1.85025716531119,4.44880856049496 -1.81816534331328 -2.00055313746909,4.69649374568015 -2.00156990171784 -2.15260104489991,4.95391442876651 -2.18320436959491 -2.30618189569452,5.2196798243396 -2.36332161701985 -2.46107669794383,5.49239914698496 -2.54217451406801 -2.61706645973871,5.77068161128813 -2.72001593081475 -2.77393218917004,6.05313643183467 -2.89709873733543 -2.93145489432872,6.33837282321012 -3.0736758037054 -3.08941558330563,6.625 -3.25 -3.24759526419165)", ) # OGRFeature(entities):67 @@ -3732,7 +3724,7 @@ def test_ogr_dxf_52(): ), "Wrong SubClasses on HELIX" ogrtest.check_feature_geometry( f, - "LINESTRING (150 120,149.345876458438 119.778561209114,148.706627788813 119.535836602547,148.082773142501 119.272634882071,147.474831670876 118.989764749454,146.883322525316 118.688034906466,146.308764857195 118.368254054878,145.75167781789 118.03123089646,145.212580558776 117.677774132981,144.691992231228 117.308692466212,144.190431986623 116.924794597921,143.708418976337 116.52688922988,143.246472351745 116.115785063858,142.805226682224 115.692350328976,142.385468357145 115.257680939095,141.987209053809 114.8126724387,141.610382578047 114.358190780749,141.254922735687 113.895101918197,140.920763332559 113.424271804003,140.607838174492 112.946566391121,140.316081067316 112.46285163251,140.04542581686 111.973993481125,139.795806228954 111.480857889924,139.567156109426 110.984310811863,139.359409264107 110.4852181999,139.172499498825 109.98444600699,139.00636061941 109.482860186091,138.860926431692 108.981326690159,138.7361307415 108.480711472151,138.631907354662 107.981880485024,138.54819007701 107.485699681734,138.484912714371 106.993035015239,138.442009072576 106.504752438495,138.419412957453 106.021717904458,138.41678542913 105.544991394258,138.433333223564 105.075482938615,138.468434844937 104.613670677827,138.521471087835 104.160029888371,138.59182274684 103.715035846723,138.678870616536 103.27916382936,138.781995491508 102.852889112758,138.900578166339 102.436686973394,139.033999435614 102.031032687745,139.181640093916 101.636401532287,139.342880935829 101.253268783496,139.517102755937 100.882109717849,139.703686348824 100.523399611823,139.902012509075 100.177613741895,140.111462031272 99.8452273845396,140.33141571 99.5267158162348,140.561254339843 99.2225543134567,140.800358715385 98.933218152682,141.04810963121 98.6591826103871,141.303887881901 98.4009229630486,141.567055122443 98.1589144355755,141.836465751876 97.9334729764931,142.111203876514 97.7245055448538,142.390570491032 97.5318567084626,142.673866590107 97.3553710351246,142.960393168413 97.194893092645,143.249451220625 97.0502674488286,143.54034174142 96.9213386714808,143.832365725473 96.8079513284064,144.124824167458 96.7099499874106,144.417018062052 96.6271792162984,144.708248403929 96.5594835828749,144.997816187765 96.5067076549452,145.285022408236 96.4686960003143,145.569168060017 96.4452931867873,145.849554137782 96.4363437821692,146.125481636209 96.4416923542652,146.396251549971 96.4611834708803,146.661164873745 96.4946616998195,146.919522602205 96.5419716088879,147.170625730027 96.6029577658907,147.413708536343 96.6773765373194,147.64790100184 96.7644518356677,147.872845806317 96.8635266377703,148.088244263586 96.9739879715066,148.293797687463 97.0952228647559,148.48920739176 97.2266183453974,148.674174690292 97.3675614413103,148.848400896871 97.5174391803741,149.011587325312 97.675638590468,149.163435289429 97.8415466994713,149.303646103034 98.0145505352631,149.431921079943 98.194037125723,149.547961533967 98.37939349873,149.651468778922 98.5700066821635,149.742144128621 98.7652637039028,149.819688896877 98.9645515918272,149.883804397505 99.1672573738159,149.934191944317 99.3727680777483,149.970552851128 99.5804707315036,149.992588431751 99.7897523629611,150 100)", + "LINESTRING Z (150 120 0,149.345876458438 119.778561209114 0.210526315789474,148.706627788813 119.535836602547 0.421052631578947,148.082773142501 119.272634882071 0.631578947368421,147.474831670876 118.989764749454 0.842105263157894,146.883322525316 118.688034906466 1.05263157894737,146.308764857195 118.368254054878 1.26315789473684,145.75167781789 118.03123089646 1.47368421052632,145.212580558776 117.677774132981 1.68421052631579,144.691992231228 117.308692466212 1.89473684210526,144.190431986623 116.924794597921 2.10526315789474,143.708418976337 116.52688922988 2.31578947368421,143.246472351745 116.115785063858 2.52631578947368,142.805226682224 115.692350328976 2.73684210526316,142.385468357145 115.257680939095 2.94736842105263,141.987209053809 114.8126724387 3.1578947368421,141.610382578047 114.358190780749 3.36842105263158,141.254922735687 113.895101918197 3.57894736842105,140.920763332559 113.424271804003 3.78947368421053,140.607838174492 112.946566391121 4,140.316081067316 112.46285163251 4.21052631578947,140.04542581686 111.973993481125 4.42105263157895,139.795806228954 111.480857889924 4.63157894736842,139.567156109426 110.984310811863 4.8421052631579,139.359409264107 110.4852181999 5.05263157894737,139.172499498825 109.98444600699 5.26315789473684,139.00636061941 109.482860186091 5.47368421052632,138.860926431692 108.981326690159 5.68421052631579,138.7361307415 108.480711472151 5.89473684210526,138.631907354662 107.981880485024 6.10526315789474,138.54819007701 107.485699681734 6.31578947368421,138.484912714371 106.993035015239 6.52631578947369,138.442009072576 106.504752438495 6.73684210526316,138.419412957453 106.021717904458 6.94736842105264,138.41678542913 105.544991394258 7.15789473684211,138.433333223564 105.075482938615 7.36842105263158,138.468434844937 104.613670677827 7.57894736842106,138.521471087835 104.160029888371 7.78947368421053,138.59182274684 103.715035846723 8.00000000000001,138.678870616536 103.27916382936 8.21052631578948,138.781995491508 102.852889112758 8.42105263157896,138.900578166339 102.436686973394 8.63157894736843,139.033999435614 102.031032687745 8.8421052631579,139.181640093916 101.636401532287 9.05263157894738,139.342880935829 101.253268783496 9.26315789473685,139.517102755937 100.882109717849 9.47368421052633,139.703686348824 100.523399611823 9.6842105263158,139.902012509075 100.177613741895 9.89473684210528,140.111462031272 99.8452273845396 10.1052631578948,140.33141571 99.5267158162348 10.3157894736842,140.561254339843 99.2225543134567 10.5263157894737,140.800358715385 98.933218152682 10.7368421052632,141.04810963121 98.6591826103871 10.9473684210526,141.303887881901 98.4009229630486 11.1578947368421,141.567055122443 98.1589144355755 11.3684210526316,141.836465751876 97.9334729764931 11.5789473684211,142.111203876514 97.7245055448538 11.7894736842105,142.390570491032 97.5318567084626 12,142.673866590107 97.3553710351246 12.2105263157895,142.960393168413 97.194893092645 12.421052631579,143.249451220625 97.0502674488286 12.6315789473684,143.54034174142 96.9213386714808 12.8421052631579,143.832365725473 96.8079513284064 13.0526315789474,144.124824167458 96.7099499874106 13.2631578947369,144.417018062052 96.6271792162984 13.4736842105263,144.708248403929 96.5594835828749 13.6842105263158,144.997816187765 96.5067076549452 13.8947368421053,145.285022408236 96.4686960003143 14.1052631578948,145.569168060017 96.4452931867873 14.3157894736842,145.849554137782 96.4363437821692 14.5263157894737,146.125481636209 96.4416923542652 14.7368421052632,146.396251549971 96.4611834708803 14.9473684210527,146.661164873745 96.4946616998195 15.1578947368421,146.919522602205 96.5419716088879 15.3684210526316,147.170625730027 96.6029577658907 15.5789473684211,147.413708536343 96.6773765373194 15.7894736842105,147.64790100184 96.7644518356677 16,147.872845806317 96.8635266377703 16.2105263157895,148.088244263586 96.9739879715066 16.421052631579,148.293797687463 97.0952228647559 16.6315789473684,148.48920739176 97.2266183453974 16.8421052631579,148.674174690292 97.3675614413103 17.0526315789474,148.848400896871 97.5174391803741 17.2631578947369,149.011587325312 97.675638590468 17.4736842105263,149.163435289429 97.8415466994713 17.6842105263158,149.303646103034 98.0145505352631 17.8947368421053,149.431921079943 98.194037125723 18.1052631578948,149.547961533967 98.37939349873 18.3157894736842,149.651468778922 98.5700066821635 18.5263157894737,149.742144128621 98.7652637039028 18.7368421052632,149.819688896877 98.9645515918272 18.9473684210527,149.883804397505 99.1672573738159 19.1578947368421,149.934191944317 99.3727680777483 19.3684210526316,149.970552851128 99.5804707315036 19.5789473684211,149.992588431751 99.7897523629611 19.7894736842106,150 100 20)", context="HELIX", ) @@ -3843,7 +3835,7 @@ def test_ogr_dxf_52(): f = lyr.GetNextFeature() ogrtest.check_feature_geometry( f, - "LINESTRING (0 20,0.513272464826192 19.8251653183892,1.00815682586353 19.629626397244,1.48499546839613 19.4132825350102,1.94413077770813 19.1760330301337,2.38590513908363 18.9177771810603,2.81066093780676 18.6384142862359,3.21874055916165 18.3378436441062,3.61048638843241 18.0159645531172,3.98624081090316 17.6726763117148,4.34634621185803 17.3078782183446,4.69114497658114 16.9214695714527,5.02097949035661 16.5133496694848,5.33619213846856 16.0834178108867,5.63712530620111 15.6315732941045,5.92412137883838 15.1577154175837,6.1975227416645 14.6617434797705,6.45767177996359 14.1435567791104,6.70491087901976 13.6030546140496,6.93958242411715 13.0401362830336,7.16202880053986 12.4547010845085,7.37259239357203 11.8466483169201,7.57161558849776 11.2158772787141,7.7594407706012 10.5622872683365,7.93641032516645 9.88577758423314,8.10286663747763 9.18624752484979,8.25915209281888 8.46359638863234,8.4056090764743 7.71772347402662,8.54257997372803 6.94852807947849,8.67040716986418 6.1559095034338,8.78943305016688 5.33976704433838,8.9 4.5)", + "LINESTRING Z (0 20 0,0.513272464826192 19.8251653183892 0,1.00815682586353 19.629626397244 0,1.48499546839613 19.4132825350102 0,1.94413077770813 19.1760330301337 0,2.38590513908363 18.9177771810603 0,2.81066093780676 18.6384142862359 0,3.21874055916165 18.3378436441062 0,3.61048638843241 18.0159645531172 0,3.98624081090316 17.6726763117148 0,4.34634621185803 17.3078782183446 0,4.69114497658114 16.9214695714527 0,5.02097949035661 16.5133496694848 0,5.33619213846856 16.0834178108867 0,5.63712530620111 15.6315732941045 0,5.92412137883838 15.1577154175837 0,6.1975227416645 14.6617434797705 0,6.45767177996359 14.1435567791104 0,6.70491087901976 13.6030546140496 0,6.93958242411715 13.0401362830336 0,7.16202880053986 12.4547010845085 0,7.37259239357203 11.8466483169201 0,7.57161558849776 11.2158772787141 0,7.7594407706012 10.5622872683365 0,7.93641032516645 9.88577758423314 0,8.10286663747763 9.18624752484979 0,8.25915209281888 8.46359638863234 0,8.4056090764743 7.71772347402662 0,8.54257997372803 6.94852807947849 0,8.67040716986418 6.1559095034338 0,8.78943305016688 5.33976704433838 0,8.9 4.5 0)", context="SPLINE", ) diff --git a/autotest/ogr/ogr_edigeo.py b/autotest/ogr/ogr_edigeo.py index 63e1e6276830..66b42e578c1d 100755 --- a/autotest/ogr/ogr_edigeo.py +++ b/autotest/ogr/ogr_edigeo.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_eeda.py b/autotest/ogr/ogr_eeda.py index 8360d2eb109e..a08ce389d481 100755 --- a/autotest/ogr/ogr_eeda.py +++ b/autotest/ogr/ogr_eeda.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_elasticsearch.py b/autotest/ogr/ogr_elasticsearch.py index 7824a7f340fe..c6f22e9b4fbe 100755 --- a/autotest/ogr/ogr_elasticsearch.py +++ b/autotest/ogr/ogr_elasticsearch.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_esrijson.py b/autotest/ogr/ogr_esrijson.py index 0c96b870f6d6..fd11a2ce5dc4 100755 --- a/autotest/ogr/ogr_esrijson.py +++ b/autotest/ogr/ogr_esrijson.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009-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. +# SPDX-License-Identifier: MIT ############################################################################### import contextlib diff --git a/autotest/ogr/ogr_factory.py b/autotest/ogr/ogr_factory.py index d1a7c1a8cf6e..6de4499166d2 100755 --- a/autotest/ogr/ogr_factory.py +++ b/autotest/ogr/ogr_factory.py @@ -11,23 +11,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_feature.py b/autotest/ogr/ogr_feature.py index 51a9713feaa4..be2db1812bb9 100755 --- a/autotest/ogr/ogr_feature.py +++ b/autotest/ogr/ogr_feature.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest @@ -923,6 +907,7 @@ def test_ogr_feature_GetFieldAsISO8601DateTime(): assert feature.GetFieldAsISO8601DateTime("field_datetime") == "" +@pytest.mark.require_driver("MapInfo File") def test_ogr_feature_dump_readable(): ds = ogr.Open("data/mitab/single_point_mapinfo.tab") diff --git a/autotest/ogr/ogr_fgdb.py b/autotest/ogr/ogr_fgdb.py index 12c47f51e3bb..efdafd567434 100755 --- a/autotest/ogr/ogr_fgdb.py +++ b/autotest/ogr/ogr_fgdb.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_fgdb_stress_test.py b/autotest/ogr/ogr_fgdb_stress_test.py index fb42898fb24f..e72a6e87cab1 100755 --- a/autotest/ogr/ogr_fgdb_stress_test.py +++ b/autotest/ogr/ogr_fgdb_stress_test.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_fielddomain.py b/autotest/ogr/ogr_fielddomain.py index 92872940438c..8994bf5d7779 100755 --- a/autotest/ogr/ogr_fielddomain.py +++ b/autotest/ogr/ogr_fielddomain.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/ogr/ogr_flatgeobuf.py b/autotest/ogr/ogr_flatgeobuf.py index 60bb994b3b16..bdbd0819e106 100644 --- a/autotest/ogr/ogr_flatgeobuf.py +++ b/autotest/ogr/ogr_flatgeobuf.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018-2019, Björn Harrtell # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -1431,3 +1415,152 @@ def test_ogr_flatgeobuf_write_mismatch_geom_type(tmp_vsimem): match="ICreateFeature: Mismatched geometry type. Feature geometry type is Line String, expected layer geometry type is Point", ): lyr.CreateFeature(f) + + +############################################################################### +# Test OGRGenSQLResultLayer::GetArrowStream() implementation. +# There isn't much specific of the FlatGeoBuf driver, except it is the +# only one in a default build that implements OLCFastGetArrowStream and doesn't +# have a specialized ExecuteSQL() implementation. + + +@gdaltest.enable_exceptions() +def test_ogr_flatgeobuf_sql_arrow(tmp_vsimem): + + filename = str(tmp_vsimem / "temp.fgb") + with ogr.GetDriverByName("FlatGeoBuf").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test", geom_type=ogr.wkbPoint) + lyr.CreateField(ogr.FieldDefn("foo")) + lyr.CreateField(ogr.FieldDefn("bar")) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "bar" + f["bar"] = "baz" + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT (1 2)")) + lyr.CreateFeature(f) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "bar2" + f["bar"] = "baz2" + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT (3 4)")) + lyr.CreateFeature(f) + + with ogr.Open(filename) as ds: + with ds.ExecuteSQL("SELECT 'a' FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + tmp_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + tmp_lyr = tmp_ds.CreateLayer("test") + tmp_lyr.WriteArrow(lyr) + f = tmp_lyr.GetNextFeature() + assert f["FIELD_1"] == "a" + + with ds.ExecuteSQL("SELECT foo, foo FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT CONCAT(foo, 'x') FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT foo AS renamed, foo FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT bar, foo FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT CAST(foo AS float) FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT MIN(foo) FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT COUNT(*) FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT * FROM test a JOIN test b ON a.foo = b.foo") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT * FROM test OFFSET 1") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT * FROM test ORDER BY foo") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT *, OGR_STYLE HIDDEN FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT DISTINCT foo FROM test") as lyr: + assert not lyr.TestCapability(ogr.OLCFastGetArrowStream) + + with ds.ExecuteSQL("SELECT * FROM test") as lyr: + try: + stream = lyr.GetArrowStreamAsNumPy() + except ImportError: + stream = None + if stream: + with pytest.raises( + Exception, + match=r"Calling get_next\(\) on a freed OGRLayer is not supported", + ): + [batch for batch in stream] + + sql = "SELECT foo, bar AS bar_renamed FROM test" + with ds.ExecuteSQL(sql) as lyr: + assert lyr.TestCapability(ogr.OLCFastGetArrowStream) + + tmp_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + tmp_lyr = tmp_ds.CreateLayer("test") + tmp_lyr.WriteArrow(lyr) + assert tmp_lyr.GetLayerDefn().GetFieldCount() == 2 + assert tmp_lyr.GetLayerDefn().GetFieldDefn(0).GetName() == "foo" + assert tmp_lyr.GetLayerDefn().GetFieldDefn(1).GetName() == "bar_renamed" + assert tmp_lyr.GetFeatureCount() == 2 + f = tmp_lyr.GetNextFeature() + assert f["foo"] == "bar2" + assert f["bar_renamed"] == "baz2" + assert f.GetGeometryRef().ExportToWkt() == "POINT (3 4)" + f = tmp_lyr.GetNextFeature() + assert f["foo"] == "bar" + assert f["bar_renamed"] == "baz" + assert f.GetGeometryRef().ExportToWkt() == "POINT (1 2)" + + sql = "SELECT bar FROM test LIMIT 1" + with ds.ExecuteSQL(sql) as lyr: + assert lyr.TestCapability(ogr.OLCFastGetArrowStream) + + tmp_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + tmp_lyr = tmp_ds.CreateLayer("test") + tmp_lyr.WriteArrow(lyr) + assert tmp_lyr.GetLayerDefn().GetFieldCount() == 1 + assert tmp_lyr.GetFeatureCount() == 1 + f = tmp_lyr.GetNextFeature() + assert f["bar"] == "baz2" + assert f.GetGeometryRef().ExportToWkt() == "POINT (3 4)" + + sql = "SELECT * EXCLUDE (\"_ogr_geometry_\") FROM test WHERE foo = 'bar'" + with ds.ExecuteSQL(sql) as lyr: + assert lyr.TestCapability(ogr.OLCFastGetArrowStream) + + tmp_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + tmp_lyr = tmp_ds.CreateLayer("test") + tmp_lyr.WriteArrow(lyr) + assert tmp_lyr.GetFeatureCount() == 1 + f = tmp_lyr.GetNextFeature() + assert f["foo"] == "bar" + assert f["bar"] == "baz" + assert f.GetGeometryRef() is None + + sql = "SELECT * FROM test" + with ds.ExecuteSQL(sql) as lyr: + lyr.SetSpatialFilterRect(1, 2, 1, 2) + assert lyr.TestCapability(ogr.OLCFastGetArrowStream) + + tmp_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + tmp_lyr = tmp_ds.CreateLayer("test") + tmp_lyr.WriteArrow(lyr) + assert tmp_lyr.GetLayerDefn().GetFieldCount() == 2 + assert tmp_lyr.GetLayerDefn().GetFieldDefn(0).GetName() == "foo" + assert tmp_lyr.GetLayerDefn().GetFieldDefn(1).GetName() == "bar" + assert tmp_lyr.GetFeatureCount() == 1 + f = tmp_lyr.GetNextFeature() + assert f["foo"] == "bar" + assert f["bar"] == "baz" + assert f.GetGeometryRef().ExportToWkt() == "POINT (1 2)" + f = tmp_lyr.GetNextFeature() diff --git a/autotest/ogr/ogr_geoconcept.py b/autotest/ogr/ogr_geoconcept.py index 42290916a6e8..32df14e4e900 100755 --- a/autotest/ogr/ogr_geoconcept.py +++ b/autotest/ogr/ogr_geoconcept.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2008, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ogrtest diff --git a/autotest/ogr/ogr_geojson.py b/autotest/ogr/ogr_geojson.py index 59da4f8c4e10..d80279983b3b 100755 --- a/autotest/ogr/ogr_geojson.py +++ b/autotest/ogr/ogr_geojson.py @@ -1806,7 +1806,11 @@ def test_ogr_geojson_48(tmp_vsimem): # Test UpdateFeature() support -def test_ogr_geojson_update_feature(tmp_vsimem): +@pytest.mark.parametrize("check_after_update_before_reopen", [True, False]) +@pytest.mark.parametrize("sync_to_disk_after_update", [True, False]) +def test_ogr_geojson_update_feature( + tmp_vsimem, check_after_update_before_reopen, sync_to_disk_after_update +): filename = str(tmp_vsimem / "test.json") @@ -1821,13 +1825,21 @@ def test_ogr_geojson_update_feature(tmp_vsimem): lyr = ds.GetLayer(0) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(0) - f["int64list"] = [123456790123, -123456790123] + f["int64list"] = [-123456790123, 123456790123] lyr.UpdateFeature(f, [0], [], False) + if sync_to_disk_after_update: + lyr.SyncToDisk() + + if check_after_update_before_reopen: + lyr.ResetReading() + f = lyr.GetNextFeature() + assert f["int64list"] == [-123456790123, 123456790123] + with ogr.Open(filename) as ds: lyr = ds.GetLayer(0) f = lyr.GetNextFeature() - assert f["int64list"] == [123456790123, -123456790123] + assert f["int64list"] == [-123456790123, 123456790123] ############################################################################### @@ -4593,7 +4605,7 @@ def test_ogr_geojson_arrow_stream_pyarrow_mixed_timezone(tmp_vsimem): def test_ogr_geojson_arrow_stream_pyarrow_utc_plus_five(tmp_vsimem): - pytest.importorskip("pyarrow") + # pytest.importorskip("pyarrow") filename = str( tmp_vsimem / "test_ogr_geojson_arrow_stream_pyarrow_utc_plus_five.geojson" @@ -4609,22 +4621,37 @@ def test_ogr_geojson_arrow_stream_pyarrow_utc_plus_five(tmp_vsimem): lyr.CreateFeature(f) ds = None + try: + import pyarrow # NOQA + + has_pyarrow = True + except ImportError: + has_pyarrow = False + if has_pyarrow: + ds = ogr.Open(filename) + lyr = ds.GetLayer(0) + stream = lyr.GetArrowStreamAsPyArrow() + assert stream.schema.field("datetime").type.tz == "+05:00" + values = [] + for batch in stream: + for x in batch.field("datetime"): + values.append(x.value) + assert values == [1653982496789, 1653986096789] + + mem_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + mem_lyr = mem_ds.CreateLayer("test", geom_type=ogr.wkbPoint) ds = ogr.Open(filename) lyr = ds.GetLayer(0) - stream = lyr.GetArrowStreamAsPyArrow() - assert stream.schema.field("datetime").type.tz == "+05:00" - values = [] - for batch in stream: - for x in batch.field("datetime"): - values.append(x.value) - assert values == [1654000496789, 1654004096789] + mem_lyr.WriteArrow(lyr) + + f = mem_lyr.GetNextFeature() + assert f["datetime"] == "2022/05/31 12:34:56.789+05" ############################################################################### def test_ogr_geojson_arrow_stream_pyarrow_utc_minus_five(tmp_vsimem): - pytest.importorskip("pyarrow") filename = str( tmp_vsimem / "test_ogr_geojson_arrow_stream_pyarrow_utc_minus_five.geojson" @@ -4640,22 +4667,37 @@ def test_ogr_geojson_arrow_stream_pyarrow_utc_minus_five(tmp_vsimem): lyr.CreateFeature(f) ds = None + try: + import pyarrow # NOQA + + has_pyarrow = True + except ImportError: + has_pyarrow = False + if has_pyarrow: + ds = ogr.Open(filename) + lyr = ds.GetLayer(0) + stream = lyr.GetArrowStreamAsPyArrow() + assert stream.schema.field("datetime").type.tz == "-05:00" + values = [] + for batch in stream: + for x in batch.field("datetime"): + values.append(x.value) + assert values == [1654018496789, 1654022096789] + + mem_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + mem_lyr = mem_ds.CreateLayer("test", geom_type=ogr.wkbPoint) ds = ogr.Open(filename) lyr = ds.GetLayer(0) - stream = lyr.GetArrowStreamAsPyArrow() - assert stream.schema.field("datetime").type.tz == "-05:00" - values = [] - for batch in stream: - for x in batch.field("datetime"): - values.append(x.value) - assert values == [1654000496789, 1654004096789] + mem_lyr.WriteArrow(lyr) + + f = mem_lyr.GetNextFeature() + assert f["datetime"] == "2022/05/31 12:34:56.789-05" ############################################################################### def test_ogr_geojson_arrow_stream_pyarrow_unknown_timezone(tmp_vsimem): - pytest.importorskip("pyarrow") filename = str( tmp_vsimem / "test_ogr_geojson_arrow_stream_pyarrow_unknown_timezone.geojson" @@ -4671,15 +4713,33 @@ def test_ogr_geojson_arrow_stream_pyarrow_unknown_timezone(tmp_vsimem): lyr.CreateFeature(f) ds = None + try: + import pyarrow # NOQA + + has_pyarrow = True + except ImportError: + has_pyarrow = False + if has_pyarrow: + ds = ogr.Open(filename) + lyr = ds.GetLayer(0) + stream = lyr.GetArrowStreamAsPyArrow() + assert stream.schema.field("datetime").type.tz is None + values = [] + for batch in stream: + for x in batch.field("datetime"): + values.append(x.value) + assert values == [1654000496789, 1654004096789] + + mem_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + mem_lyr = mem_ds.CreateLayer("test", geom_type=ogr.wkbPoint) ds = ogr.Open(filename) lyr = ds.GetLayer(0) - stream = lyr.GetArrowStreamAsPyArrow() - assert stream.schema.field("datetime").type.tz is None - values = [] - for batch in stream: - for x in batch.field("datetime"): - values.append(x.value) - assert values == [1654000496789, 1654004096789] + mem_lyr.WriteArrow(lyr) + + f = mem_lyr.GetNextFeature() + # We have lost the timezone info here, as there's no way in Arrow to + # have a mixed of with and without timezone in a single column + assert f["datetime"] == "2022/05/31 12:34:56.789" ############################################################################### diff --git a/autotest/ogr/ogr_geojsonseq.py b/autotest/ogr/ogr_geojsonseq.py index 89acd3a61ca9..c041f1735b06 100755 --- a/autotest/ogr/ogr_geojsonseq.py +++ b/autotest/ogr/ogr_geojsonseq.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -34,6 +18,8 @@ from osgeo import gdal, ogr, osr +pytestmark = pytest.mark.require_driver("GeoJSONSeq") + def _ogr_geojsonseq_create(filename, lco, expect_rs): diff --git a/autotest/ogr/ogr_geom.py b/autotest/ogr/ogr_geom.py index 935176d7c4f2..67911355b88c 100755 --- a/autotest/ogr/ogr_geom.py +++ b/autotest/ogr/ogr_geom.py @@ -3986,21 +3986,57 @@ def test_ogr_geom_makevalid(): g, "MULTIPOLYGON (((0 0,5 5,10 0,0 0)),((5 5,0 10,10 10,5 5)))" ) - if ( - ogr.GetGEOSVersionMajor() * 10000 - + ogr.GetGEOSVersionMinor() * 100 - + ogr.GetGEOSVersionMicro() - >= 31000 - ): - g = ogr.CreateGeometryFromWkt( - "POLYGON ((0 0,0 10,10 10,10 0,0 0),(5 5,15 10,15 0,5 5))" - ) - # Only since GEOS 3.10 - g = g.MakeValid(["METHOD=STRUCTURE"]) - if g is not None: - ogrtest.check_feature_geometry( - g, "POLYGON ((0 10,10 10,10.0 7.5,5 5,10.0 2.5,10 0,0 0,0 10))" - ) + +############################################################################### + + +@pytest.mark.require_geos(3, 10, 0) +def test_ogr_geom_makevalid_structure(): + + g = ogr.CreateGeometryFromWkt( + "POLYGON ((0 0,0 10,10 10,10 0,0 0),(5 5,15 10,15 0,5 5))" + ) + g = g.MakeValid(["METHOD=STRUCTURE"]) + ogrtest.check_feature_geometry( + g, "POLYGON ((0 10,10 10,10.0 7.5,5 5,10.0 2.5,10 0,0 0,0 10))" + ) + + # Already valid multi-polygon made of a single-part + g = ogr.CreateGeometryFromWkt("MULTIPOLYGON (((0 0,1 0,1 1,0 1,0 0)))") + g = g.MakeValid(["METHOD=STRUCTURE"]) + assert ( + g.ExportToIsoWkt() == "MULTIPOLYGON (((0 0,1 0,1 1,0 1,0 0)))" + or g.ExportToIsoWkt() == "MULTIPOLYGON (((0 0,0 1,1 1,1 0,0 0)))" + ) + + # Already valid multi-polygon made of a single-part, with duplicated point + g = ogr.CreateGeometryFromWkt("MULTIPOLYGON (((0 0,1 0,1 0,1 1,0 1,0 0)))") + g = g.MakeValid(["METHOD=STRUCTURE"]) + assert ( + g.ExportToIsoWkt() == "MULTIPOLYGON (((0 0,1 0,1 1,0 1,0 0)))" + or g.ExportToIsoWkt() == "MULTIPOLYGON (((0 0,0 1,1 1,1 0,0 0)))" + ) + + # Already valid multi-polygon made of a single-part + g = ogr.CreateGeometryFromWkt( + "MULTIPOLYGON Z (((0 0 10,1 0 10,1 1 10,0 1 10,0 0 10)))" + ) + g = g.MakeValid(["METHOD=STRUCTURE"]) + assert ( + g.ExportToIsoWkt() == "MULTIPOLYGON Z (((0 0 10,1 0 10,1 1 10,0 1 10,0 0 10)))" + or g.ExportToIsoWkt() + == "MULTIPOLYGON Z (((0 0 10,0 1 10,1 1 10,1 0 10,0 0 10)))" + ) + + # Already valid geometry collection + g = ogr.CreateGeometryFromWkt( + "GEOMETRYCOLLECTION (POLYGON ((0 0,1 0,1 1,0 1,0 0)))" + ) + g = g.MakeValid(["METHOD=STRUCTURE"]) + assert ( + g.ExportToIsoWkt() == "GEOMETRYCOLLECTION (POLYGON ((0 0,1 0,1 1,0 1,0 0)))" + or g.ExportToIsoWkt() == "GEOMETRYCOLLECTION (POLYGON ((0 0,0 1,1 1,1 0,0 0)))" + ) ############################################################################### diff --git a/autotest/ogr/ogr_geomcoordinateprecision.py b/autotest/ogr/ogr_geomcoordinateprecision.py index bb070410c47f..ddd11dd3e5de 100755 --- a/autotest/ogr/ogr_geomcoordinateprecision.py +++ b/autotest/ogr/ogr_geomcoordinateprecision.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/ogr/ogr_georss.py b/autotest/ogr/ogr_georss.py index 4019e22144eb..5387d45585b1 100755 --- a/autotest/ogr/ogr_georss.py +++ b/autotest/ogr/ogr_georss.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_gml.py b/autotest/ogr/ogr_gml.py index d4624b100a7b..da3a16c808e6 100755 --- a/autotest/ogr/ogr_gml.py +++ b/autotest/ogr/ogr_gml.py @@ -11,23 +11,7 @@ # Copyright (c) 2006, Frank Warmerdam # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -2558,6 +2542,25 @@ def test_ogr_gml_64(parser): assert feat is not None, parser +############################################################################### +# Test we don't spend too much time parsing documents featuring the billion +# laugh attack + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize("parser", ("XERCES", "EXPAT")) +def test_ogr_gml_billion_laugh(parser): + + with gdal.config_option("GML_PARSER", parser), pytest.raises( + Exception, match="File probably corrupted" + ): + with gdal.OpenEx("data/gml/billionlaugh.gml") as ds: + assert ds.GetDriver().GetDescription() == "GML" + for lyr in ds: + for f in lyr: + pass + + ############################################################################### # Test SRSDIMENSION_LOC=GEOMETRY option (#5606) @@ -4626,3 +4629,18 @@ def test_ogr_gml_get_layers_by_name_from_imported_schema_more_tests(tmp_path): assert isinstance( dat_erst, list ), f"Expected 'dat_erst' to be of type 'list', but got {type(dat_erst)}" + + +############################################################################### +# Test force opening a GML file + + +def test_ogr_gml_force_opening(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gml") + gdal.FileFromMemBuffer(filename, open("data/nas/empty_nas.xml", "rb").read()) + + # Would be opened by NAS driver if not forced + with gdal.config_option("NAS_GFS_TEMPLATE", ""): + ds = gdal.OpenEx(filename, allowed_drivers=["GML"]) + assert ds.GetDriver().GetDescription() == "GML" diff --git a/autotest/ogr/ogr_gml_fgd_read.py b/autotest/ogr/ogr_gml_fgd_read.py index c3d9920253e4..3c1f305d5ad4 100755 --- a/autotest/ogr/ogr_gml_fgd_read.py +++ b/autotest/ogr/ogr_gml_fgd_read.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Hiroshi Miura # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_gmlas.py b/autotest/ogr/ogr_gmlas.py index d3a82e6467c9..5f333300d3d9 100755 --- a/autotest/ogr/ogr_gmlas.py +++ b/autotest/ogr/ogr_gmlas.py @@ -13,23 +13,7 @@ # ****************************************************************************** # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import difflib @@ -598,7 +582,7 @@ def test_ogr_gmlas_abstractgeometry(): # Test validation against schema -class MyHandler(object): +class MyHandler: def __init__(self): self.error_list = [] @@ -3485,3 +3469,19 @@ def test_ogr_gmlas_ossfuzz_70511(): Exception, match="Cannot get type definition for attribute y" ): gdal.OpenEx("GMLAS:", open_options=["XSD=data/gmlas/test_ossfuzz_70511.xsd"]) + + +############################################################################### +# Test we don't spend too much time parsing documents featuring the billion +# laugh attack + + +@gdaltest.enable_exceptions() +def test_ogr_gmlas_billion_laugh(): + + with gdal.quiet_errors(), pytest.raises(Exception, match="File probably corrupted"): + with gdal.OpenEx("GMLAS:data/gml/billionlaugh.gml") as ds: + assert ds.GetDriver().GetDescription() == "GMLAS" + for lyr in ds: + for f in lyr: + pass diff --git a/autotest/ogr/ogr_gmt.py b/autotest/ogr/ogr_gmt.py index 3ca15b56f6ff..5d178a2be551 100755 --- a/autotest/ogr/ogr_gmt.py +++ b/autotest/ogr/ogr_gmt.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_gpkg.py b/autotest/ogr/ogr_gpkg.py index ffa43ed1e6e2..3d8ad7ceb46a 100755 --- a/autotest/ogr/ogr_gpkg.py +++ b/autotest/ogr/ogr_gpkg.py @@ -11,23 +11,7 @@ # Copyright (c) 2004, Paul Ramsey # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import math @@ -92,10 +76,9 @@ def gpkg_ds(gpkg_dsn): return ogr.GetDriverByName("GPKG").CreateDataSource(gpkg_dsn) -@pytest.fixture() -def tpoly(gpkg_ds, poly_feat): +def create_test_layer(ds, src_features, layer_name): - lyr = gpkg_ds.CreateLayer("tpoly") + lyr = ds.CreateLayer(layer_name) ogrtest.quick_create_layer_def( lyr, @@ -110,11 +93,21 @@ def tpoly(gpkg_ds, poly_feat): dst_feat = ogr.Feature(feature_def=lyr.GetLayerDefn()) - for feat in poly_feat: + for feat in src_features: dst_feat.SetFrom(feat) lyr.CreateFeature(dst_feat) +@pytest.fixture() +def tpoly(gpkg_ds, poly_feat): + create_test_layer(gpkg_ds, poly_feat, "tpoly") + + +@pytest.fixture() +def tpoly_dbl_quote(gpkg_ds, poly_feat): + create_test_layer(gpkg_ds, poly_feat, 'tpoly"dbl_quote') + + @pytest.fixture() def a_layer(gpkg_ds): gpkg_ds.CreateLayer("a_layer", options=["SPATIAL_INDEX=NO"]) @@ -239,10 +232,9 @@ def get_sqlite_version(): ds = ogr.Open(":memory:") if ds is None: return (0, 0, 0) - sql_lyr = ds.ExecuteSQL("SELECT sqlite_version()") - f = sql_lyr.GetNextFeature() - version = f.GetField(0) - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT sqlite_version()") as sql_lyr: + f = sql_lyr.GetNextFeature() + version = f.GetField(0) return tuple([int(x) for x in version.split(".")[0:3]]) @@ -387,11 +379,10 @@ def test_ogr_gpkg_3(gpkg_ds, tmp_path): assert lyr1.GetName() == "a_layer", "unexpected layer name for layer 1" - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE name = 'gpkg_extensions'" - ) - assert sql_lyr.GetFeatureCount() == 0 - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 ############################################################################### @@ -418,6 +409,177 @@ def test_ogr_gpkg_5(gpkg_ds): assert gpkg_ds.GetLayerCount() == 0, "unexpected number of layers (not 0)" +############################################################################### +# Truncate a spatial layer + + +@pytest.mark.usefixtures("tpoly_dbl_quote") +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_spatial_layer(gpkg_ds, poly_feat): + + gpkg_ds.ExecuteSQL('DELETE FROM "tpoly""dbl_quote"') + + lyr = gpkg_ds.GetLayer(0) + assert lyr.GetFeatureCount() == 0 + + # Re-insert records + dst_feat = ogr.Feature(feature_def=lyr.GetLayerDefn()) + for feat in poly_feat: + dst_feat.SetFrom(feat) + lyr.CreateFeature(dst_feat) + + # Check that spatial index works fine + for feat in poly_feat: + minx, maxx, miny, maxy = feat.GetGeometryRef().GetEnvelope() + lyr.SetSpatialFilterRect(minx, miny, maxx, maxy) + assert lyr.GetFeatureCount() >= 1 + + +############################################################################### +# Truncate a non-spatial layer + + +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_non_spatial_layer(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test", geom_type=ogr.wkbNone) + lyr.CreateField(ogr.FieldDefn("foo")) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "bar" + lyr.CreateFeature(f) + + # Test that the optimization doesn't trigger when there's a WHERE clause + with ogr.Open(filename, update=1) as ds: + ds.ExecuteSQL("DELETE FROM test WHERE 0") + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 1 + + with ogr.Open(filename, update=1) as ds: + ds.ExecuteSQL("DELETE FROM test") + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 0 + + with ogr.Open(filename) as ds: + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 0 + + +############################################################################### +# Truncate a layer with a custom trigger + + +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_with_custom_trigger(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test", geom_type=ogr.wkbNone) + lyr.CreateField(ogr.FieldDefn("foo")) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "bar" + lyr.CreateFeature(f) + ds.ExecuteSQL( + "CREATE TABLE counter(table_name TEXT UNIQUE NOT NULL, counter INT)" + ) + ds.ExecuteSQL("INSERT INTO counter VALUES ('test', 1)") + ds.ExecuteSQL( + "CREATE TRIGGER my_trigger AFTER DELETE ON test BEGIN UPDATE counter SET counter = counter - 1 WHERE table_name = 'test'; END" + ) + + with ogr.Open(filename, update=1) as ds: + with ds.ExecuteSQL( + "SELECT counter FROM counter WHERE table_name = 'test'" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f["counter"] == 1 + ds.ExecuteSQL('DELETE FROM "test"') + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 0 + with ds.ExecuteSQL( + "SELECT counter FROM counter WHERE table_name = 'test'" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f["counter"] == 0 + + with ogr.Open(filename) as ds: + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 0 + + +############################################################################### +# Truncate a layer with a custom trigger that causes an error + + +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_with_custom_trigger_error(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test", geom_type=ogr.wkbNone) + lyr.CreateField(ogr.FieldDefn("foo")) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "bar" + lyr.CreateFeature(f) + ds.ExecuteSQL( + "CREATE TABLE counter(table_name TEXT UNIQUE NOT NULL, counter INT)" + ) + ds.ExecuteSQL("INSERT INTO counter VALUES ('test', 1)") + ds.ExecuteSQL( + "CREATE TRIGGER my_trigger AFTER DELETE ON test BEGIN SELECT RAISE(ABORT, 'error from trigger'); END" + ) + + with ogr.Open(filename, update=1) as ds: + with ds.ExecuteSQL( + "SELECT counter FROM counter WHERE table_name = 'test'" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f["counter"] == 1 + with pytest.raises(Exception, match="error from trigger"): + ds.ExecuteSQL('DELETE FROM "test"') + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 1 + with ds.ExecuteSQL( + "SELECT counter FROM counter WHERE table_name = 'test'" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f["counter"] == 1 + + with ogr.Open(filename) as ds: + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 1 + + +############################################################################### +# Truncate a layer in read-only mode (error) + + +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_read_only_mode(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + ds.CreateLayer("test") + + with ogr.Open(filename) as ds: + with pytest.raises(Exception, match="read-only"): + ds.ExecuteSQL('DELETE FROM "test"') + + +############################################################################### +# Truncate a layer that doe not exist + + +@gdaltest.enable_exceptions() +def test_ogr_gpkg_truncate_non_existing_table(tmp_vsimem): + + filename = str(tmp_vsimem / "test.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + with pytest.raises(Exception, match="no such table"): + ds.ExecuteSQL('DELETE FROM "i_do_not_exist"') + + ############################################################################### # Add fields @@ -461,13 +623,27 @@ def test_ogr_gpkg_6(gpkg_ds, tmp_path): def test_ogr_gpkg_7(gpkg_ds): + def get_feature_count_from_gpkg_contents(): + with gpkg_ds.ExecuteSQL( + 'SELECT feature_count FROM gpkg_ogr_contents WHERE table_name = "field_test_layer"', + dialect="DEBUG", + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + ret = f.GetField(0) + return ret lyr = gpkg_ds.CreateLayer("field_test_layer", geom_type=ogr.wkbPoint) field_defn = ogr.FieldDefn("dummy", ogr.OFTString) lyr.CreateField(field_defn) + gpkg_ds.SyncToDisk() + + assert get_feature_count_from_gpkg_contents() == 0 + gpkg_ds = gdaltest.reopen(gpkg_ds, update=1) + assert get_feature_count_from_gpkg_contents() == 0 + lyr = gpkg_ds.GetLayerByName("field_test_layer") geom = ogr.CreateGeometryFromWkt("POINT(10 10)") feat = ogr.Feature(lyr.GetLayerDefn()) @@ -480,6 +656,9 @@ def test_ogr_gpkg_7(gpkg_ds): assert lyr.CreateFeature(feat) == 0, "cannot create feature" + # None is expected here since CreateFeature() has temporarily disabled triggers + assert get_feature_count_from_gpkg_contents() is None + # Read back what we just inserted lyr.ResetReading() feat_read = lyr.GetNextFeature() @@ -528,25 +707,10 @@ def test_ogr_gpkg_7(gpkg_ds): assert lyr.GetFeatureCount() == 2 - def get_feature_count_from_gpkg_contents(): - sql_lyr = gpkg_ds.ExecuteSQL( - 'SELECT feature_count FROM gpkg_ogr_contents WHERE table_name = "field_test_layer"', - dialect="DEBUG", - ) - f = sql_lyr.GetNextFeature() - ret = f.GetField(0) - gpkg_ds.ReleaseResultSet(sql_lyr) - return ret - - assert get_feature_count_from_gpkg_contents() == 2 - assert lyr.CreateFeature(ogr.Feature(lyr.GetLayerDefn())) == ogr.OGRERR_NONE assert lyr.GetFeatureCount() == 3 - # 2 is expected here since CreateFeature() has temporarily disable triggers - assert get_feature_count_from_gpkg_contents() == 2 - # Test upserting an existing feature feat.SetField("dummy", "updated") fid = feat.GetFID() @@ -554,9 +718,6 @@ def get_feature_count_from_gpkg_contents(): assert feat.GetFID() == fid - # UpsertFeature() has serialized value 3 and re-enables triggers - assert get_feature_count_from_gpkg_contents() == 3 - upserted_feat = lyr.GetFeature(feat.GetFID()) assert ( upserted_feat.GetField("dummy") == "updated" @@ -755,21 +916,20 @@ def test_ogr_gpkg_12(gpkg_ds): gpkg_ds.ExecuteSQL("ALTER TABLE tbl_linestring RENAME TO tbl_linestring_renamed;") - sql_lyr = gpkg_ds.ExecuteSQL("SELECT * FROM tbl_linestring_renamed") - assert sql_lyr.GetFIDColumn() == "fid" - assert sql_lyr.GetGeomType() == ogr.wkbLineString - assert sql_lyr.GetGeometryColumn() == "geom" - assert sql_lyr.GetSpatialRef().ExportToWkt().find("32631") >= 0 - feat = sql_lyr.GetNextFeature() - assert feat.GetFID() == 1 - assert sql_lyr.GetFeatureCount() == 10 - assert sql_lyr.GetLayerDefn().GetFieldCount() == 10 - assert sql_lyr.GetLayerDefn().GetFieldDefn(6).GetSubType() == ogr.OFSTBoolean - assert sql_lyr.GetLayerDefn().GetFieldDefn(7).GetSubType() == ogr.OFSTInt16 - assert sql_lyr.GetLayerDefn().GetFieldDefn(8).GetSubType() == ogr.OFSTFloat32 - gpkg_ds.ReleaseResultSet(sql_lyr) - - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL("SELECT * FROM tbl_linestring_renamed") as sql_lyr: + assert sql_lyr.GetFIDColumn() == "fid" + assert sql_lyr.GetGeomType() == ogr.wkbLineString + assert sql_lyr.GetGeometryColumn() == "geom" + assert sql_lyr.GetSpatialRef().ExportToWkt().find("32631") >= 0 + feat = sql_lyr.GetNextFeature() + assert feat.GetFID() == 1 + assert sql_lyr.GetFeatureCount() == 10 + assert sql_lyr.GetLayerDefn().GetFieldCount() == 10 + assert sql_lyr.GetLayerDefn().GetFieldDefn(6).GetSubType() == ogr.OFSTBoolean + assert sql_lyr.GetLayerDefn().GetFieldDefn(7).GetSubType() == ogr.OFSTInt16 + assert sql_lyr.GetLayerDefn().GetFieldDefn(8).GetSubType() == ogr.OFSTFloat32 + + with gpkg_ds.ExecuteSQL( "SELECT " "CAST(fid AS INTEGER) AS FID, " "CAST(fid AS INTEGER) AS FID, " @@ -783,46 +943,44 @@ def test_ogr_gpkg_12(gpkg_ds): "CAST(fld_binary as BLOB) as FLD_BINARY, " "CAST(fld_integer64 AS INTEGER) AS FLD_INTEGER64 " "FROM tbl_linestring_renamed" - ) - assert sql_lyr.GetFIDColumn() == "FID" - assert sql_lyr.GetGeometryColumn() == "GEOM" - assert sql_lyr.GetLayerDefn().GetFieldCount() == 5 - assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetName() == "FLD_INTEGER" - assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetType() == ogr.OFTInteger - assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetName() == "FLD_STRING" - assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetType() == ogr.OFTString - assert sql_lyr.GetLayerDefn().GetFieldDefn(2).GetName() == "FLD_REAL" - assert sql_lyr.GetLayerDefn().GetFieldDefn(2).GetType() == ogr.OFTReal - assert sql_lyr.GetLayerDefn().GetFieldDefn(3).GetName() == "FLD_BINARY" - assert sql_lyr.GetLayerDefn().GetFieldDefn(3).GetType() == ogr.OFTBinary - assert sql_lyr.GetLayerDefn().GetFieldDefn(4).GetName() == "FLD_INTEGER64" - assert sql_lyr.GetLayerDefn().GetFieldDefn(4).GetType() == ogr.OFTInteger64 - gpkg_ds.ReleaseResultSet(sql_lyr) - - sql_lyr = gpkg_ds.ExecuteSQL("SELECT * FROM tbl_linestring_renamed WHERE 0=1") - feat = sql_lyr.GetNextFeature() - assert feat is None - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFIDColumn() == "FID" + assert sql_lyr.GetGeometryColumn() == "GEOM" + assert sql_lyr.GetLayerDefn().GetFieldCount() == 5 + assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetName() == "FLD_INTEGER" + assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetType() == ogr.OFTInteger + assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetName() == "FLD_STRING" + assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetType() == ogr.OFTString + assert sql_lyr.GetLayerDefn().GetFieldDefn(2).GetName() == "FLD_REAL" + assert sql_lyr.GetLayerDefn().GetFieldDefn(2).GetType() == ogr.OFTReal + assert sql_lyr.GetLayerDefn().GetFieldDefn(3).GetName() == "FLD_BINARY" + assert sql_lyr.GetLayerDefn().GetFieldDefn(3).GetType() == ogr.OFTBinary + assert sql_lyr.GetLayerDefn().GetFieldDefn(4).GetName() == "FLD_INTEGER64" + assert sql_lyr.GetLayerDefn().GetFieldDefn(4).GetType() == ogr.OFTInteger64 + + with gpkg_ds.ExecuteSQL( + "SELECT * FROM tbl_linestring_renamed WHERE 0=1" + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat is None for sql in [ "SELECT * FROM tbl_linestring_renamed LIMIT 1", "SELECT * FROM tbl_linestring_renamed ORDER BY fld_integer LIMIT 1", "SELECT * FROM tbl_linestring_renamed UNION ALL SELECT * FROM tbl_linestring_renamed ORDER BY fld_integer LIMIT 1", ]: - sql_lyr = gpkg_ds.ExecuteSQL(sql) + with gpkg_ds.ExecuteSQL(sql) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat is not None + feat = sql_lyr.GetNextFeature() + assert feat is None + assert sql_lyr.GetFeatureCount() == 1 + + with gpkg_ds.ExecuteSQL("SELECT sqlite_version()") as sql_lyr: feat = sql_lyr.GetNextFeature() assert feat is not None - feat = sql_lyr.GetNextFeature() - assert feat is None - assert sql_lyr.GetFeatureCount() == 1 - gpkg_ds.ReleaseResultSet(sql_lyr) - - sql_lyr = gpkg_ds.ExecuteSQL("SELECT sqlite_version()") - feat = sql_lyr.GetNextFeature() - assert feat is not None - assert sql_lyr.GetLayerDefn().GetFieldCount() == 1 - assert sql_lyr.GetLayerDefn().GetGeomFieldCount() == 0 - gpkg_ds.ReleaseResultSet(sql_lyr) + assert sql_lyr.GetLayerDefn().GetFieldCount() == 1 + assert sql_lyr.GetLayerDefn().GetGeomFieldCount() == 0 ############################################################################### @@ -880,14 +1038,12 @@ def test_ogr_gpkg_14(gpkg_ds): assert f.GetGeometryRef().ExportToWkt() == "POINT EMPTY" f = None - sql_lyr = gpkg_ds.ExecuteSQL('SELECT * FROM "point_no_spi-but-with-dashes"') - res = sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL('SELECT * FROM "point_no_spi-but-with-dashes"') as sql_lyr: + res = sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) assert res == 0 - sql_lyr = gpkg_ds.ExecuteSQL('SELECT * FROM "point-with-spi-and-dashes"') - res = sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL('SELECT * FROM "point-with-spi-and-dashes"') as sql_lyr: + res = sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) assert res == 1 # Test spatial filer right away @@ -927,40 +1083,38 @@ def test_ogr_gpkg_15(gpkg_ds): gpkg_ds = gdaltest.reopen(gpkg_ds, update=1) - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_IsEmpty(geom), ST_SRID(geom), ST_GeometryType(geom), " + 'ST_MinX(geom), ST_MinY(geom), ST_MaxX(geom), ST_MaxY(geom) FROM "point_no_spi-but-with-dashes" WHERE fid = 1' - ) - feat = sql_lyr.GetNextFeature() - assert feat is not None - assert feat.GetField(0) == 0 - assert feat.GetField(1) == 32631 - assert feat.GetField(2) == "POINT" - assert feat.GetField(3) == 1000 - assert feat.GetField(4) == 30000000 - assert feat.GetField(5) == 1000 - assert feat.GetField(6) == 30000000 - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat is not None + assert feat.GetField(0) == 0 + assert feat.GetField(1) == 32631 + assert feat.GetField(2) == "POINT" + assert feat.GetField(3) == 1000 + assert feat.GetField(4) == 30000000 + assert feat.GetField(5) == 1000 + assert feat.GetField(6) == 30000000 # add an empty feature to tbl_linestring lyr = gpkg_ds.GetLayer("tbl_linestring") feat = ogr.Feature(lyr.GetLayerDefn()) assert lyr.CreateFeature(feat) == 0 - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_IsEmpty(geom), ST_SRID(geom), ST_GeometryType(geom), " + "ST_MinX(geom), ST_MinY(geom), ST_MaxX(geom), ST_MaxY(geom) FROM tbl_linestring WHERE geom IS NULL" - ) - feat = sql_lyr.GetNextFeature() - assert feat is not None - assert feat.IsFieldNull(0) - assert feat.IsFieldNull(1) - assert feat.IsFieldNull(2) - assert feat.IsFieldNull(3) - assert feat.IsFieldNull(4) - assert feat.IsFieldNull(5) - assert feat.IsFieldNull(6) - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat is not None + assert feat.IsFieldNull(0) + assert feat.IsFieldNull(1) + assert feat.IsFieldNull(2) + assert feat.IsFieldNull(3) + assert feat.IsFieldNull(4) + assert feat.IsFieldNull(5) + assert feat.IsFieldNull(6) for (expected_type, actual_type, expected_result) in [ ("POINT", "POINT", 1), @@ -970,12 +1124,12 @@ def test_ogr_gpkg_15(gpkg_ds): ("GEOMETRYCOLLECTION", "MULTIPOINT", 1), ("GEOMETRYCOLLECTION", "POINT", 0), ]: - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT GPKG_IsAssignable('%s', '%s')" % (expected_type, actual_type) - ) - feat = sql_lyr.GetNextFeature() - got_result = feat.GetField(0) - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + got_result = feat.GetField(0) + assert ( got_result == expected_result ), "expected_type=%s actual_type=%s expected_result=%d got_result=%d" % ( @@ -1016,116 +1170,87 @@ def test_ogr_gpkg_15(gpkg_ds): ]: if expected_result == 0: gdal.PushErrorHandler("CPLQuietErrorHandler") - sql_lyr = gpkg_ds.ExecuteSQL(sql) - if expected_result == 0: - gdal.PopErrorHandler() - feat = sql_lyr.GetNextFeature() - got_result = feat.GetField(0) - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL(sql) as sql_lyr: + if expected_result == 0: + gdal.PopErrorHandler() + feat = sql_lyr.GetNextFeature() + got_result = feat.GetField(0) + assert got_result == expected_result, sql # NULL argument - sql_lyr = gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS(NULL, 4326)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != -1: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS(NULL, 4326)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == -1 # NULL argument - sql_lyr = gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', NULL)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != -1: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', NULL)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == -1 # Existing entry - sql_lyr = gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', 4326)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 4326: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', 4326)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 4326 # Non existing entry - sql_lyr = gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', 1234)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != -1: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT SridFromAuthCRS('epsg', 1234)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == -1 # NULL argument - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(NULL)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != -1: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(NULL)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == -1 # Existing entry in gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(4326)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 4326: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(4326)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 4326 # New entry in gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(32633)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 32633: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(32633)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 32633 # Invalid code with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(0)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != -1: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ImportFromEPSG(0)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == -1 # NULL argument - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_Transform(NULL, 4326)") - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is not None: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_Transform(NULL, 4326)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None # Invalid geometry with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_Transform(x'00', 4326)") - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is not None: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_Transform(x'00', 4326)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None # NULL argument - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_Transform(geom, NULL) FROM tbl_linestring") - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is not None: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL( + "SELECT ST_Transform(geom, NULL) FROM tbl_linestring" + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None # Invalid target SRID=0 # GeoPackage: The record with an srs_id of 0 SHALL be used for undefined geographic coordinate reference systems. with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_Transform(geom, 0), ST_SRID(ST_Transform(geom, 0)) FROM tbl_linestring" - ) - assert sql_lyr.GetSpatialRef().ExportToWkt().find("Undefined geographic SRS") >= 0 - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is None or feat.GetField(0) != 0: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert ( + sql_lyr.GetSpatialRef().ExportToWkt().find("Undefined geographic SRS") + >= 0 + ) + feat = sql_lyr.GetNextFeature() + if feat.GetGeometryRef() is None or feat.GetField(0) != 0: + feat.DumpReadable() + pytest.fail() # Invalid source SRID=0 # GeoPackage: The record with an srs_id of 0 SHALL be used for undefined geographic coordinate reference systems. @@ -1134,183 +1259,126 @@ def test_ogr_gpkg_15(gpkg_ds): src_lyr = gpkg_ds.GetLayerByName("point-with-spi-and-dashes") assert src_lyr.GetSpatialRef().ExportToWkt().find("Undefined geographic SRS") >= 0 with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( 'SELECT ST_Transform(geom, 4326), ST_SRID(ST_Transform(geom, 4326)) FROM "point-with-spi-and-dashes"' - ) - assert sql_lyr.GetSpatialRef().ExportToWkt().find("WGS_1984") >= 0 - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is None or feat.GetField(0) != 4326: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetSpatialRef().ExportToWkt().find("WGS_1984") >= 0 + feat = sql_lyr.GetNextFeature() + if feat.GetGeometryRef() is None or feat.GetField(0) != 4326: + feat.DumpReadable() + pytest.fail() # Invalid spatialite geometry: SRID=4326,MULTIPOINT EMPTY truncated with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_Transform(x'0001E610000000000000000000000000000000000000000000000000000000000000000000007C04000000000000FE', 4326) FROM tbl_linestring" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef() is not None: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_Transform(geom, ST_SRID(geom)) FROM tbl_linestring" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef().ExportToWkt() != "LINESTRING (5 5,10 5,10 10,5 10)": - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + if feat.GetGeometryRef().ExportToWkt() != "LINESTRING (5 5,10 5,10 10,5 10)": + feat.DumpReadable() + pytest.fail() - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_SRID(ST_Transform(geom, 4326)) FROM tbl_linestring" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 4326: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 4326 # Spatialite geometry: SRID=4326,MULTIPOINT EMPTY - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_SRID(ST_Transform(x'0001E610000000000000000000000000000000000000000000000000000000000000000000007C0400000000000000FE', 4326)) FROM tbl_linestring" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 4326: - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 4326 # Error case: less than 8 bytes - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_MinX(x'00')") - feat = sql_lyr.GetNextFeature() - if feat.IsFieldSetAndNotNull(0): - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_MinX(x'00')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert not feat.IsFieldSetAndNotNull(0) # Error case: 8 wrong bytes - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_MinX(x'0001020304050607')") - feat = sql_lyr.GetNextFeature() - if feat.IsFieldSetAndNotNull(0): - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_MinX(x'0001020304050607')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert not feat.IsFieldSetAndNotNull(0) # Error case: too short blob - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_GeometryType(x'4750001100000000')") - feat = sql_lyr.GetNextFeature() - if feat.IsFieldSetAndNotNull(0): - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_GeometryType(x'4750001100000000')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert not feat.IsFieldSetAndNotNull(0) # Error case: too short blob - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_GeometryType(x'475000110000000001040000')") - feat = sql_lyr.GetNextFeature() - if feat.IsFieldSetAndNotNull(0): - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL( + "SELECT ST_GeometryType(x'475000110000000001040000')" + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert not feat.IsFieldSetAndNotNull(0) # Invalid geometry, but long enough for our purpose... - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_GeometryType(x'47500011000000000104000000')" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != "MULTIPOINT": - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + if feat.GetField(0) != "MULTIPOINT": + feat.DumpReadable() + pytest.fail() # Spatialite geometry (MULTIPOINT EMPTY) - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_GeometryType(x'00010000000000000000000000000000000000000000000000000000000000000000000000007C0400000000000000FE')" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != "MULTIPOINT": - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + if feat.GetField(0) != "MULTIPOINT": + feat.DumpReadable() + pytest.fail() # Spatialite geometry (MULTIPOINT EMPTY) - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_IsEmpty(x'00010000000000000000000000000000000000000000000000000000000000000000000000007C0400000000000000FE')" - ) - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != 1: - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == 1 # Error case: invalid geometry with gdal.quiet_errors(): - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_GeometryType(x'475000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')" - ) - feat = sql_lyr.GetNextFeature() - if feat.IsFieldSetAndNotNull(0): - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert not feat.IsFieldSetAndNotNull(0) # Error case: invalid type - sql_lyr = gpkg_ds.ExecuteSQL("SELECT GPKG_IsAssignable('POINT', NULL)") - feat = sql_lyr.GetNextFeature() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT GPKG_IsAssignable('POINT', NULL)") as sql_lyr: + sql_lyr.GetNextFeature() # Error case: invalid type - sql_lyr = gpkg_ds.ExecuteSQL("SELECT GPKG_IsAssignable(NULL, 'POINT')") - feat = sql_lyr.GetNextFeature() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT GPKG_IsAssignable(NULL, 'POINT')") as sql_lyr: + sql_lyr.GetNextFeature() # Test hstore_get_value - sql_lyr = gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', 'a')") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) != "b": - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', 'a')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == "b" # Test hstore_get_value - sql_lyr = gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', 'x')") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) is not None: - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', 'x')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) is None # Error case: invalid type - sql_lyr = gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', NULL)") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) is not None: - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT hstore_get_value('a=>b', NULL)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) is None # Error case: invalid type - sql_lyr = gpkg_ds.ExecuteSQL("SELECT hstore_get_value(NULL, 'a')") - feat = sql_lyr.GetNextFeature() - if feat.GetField(0) is not None: - feat.DumpReadable() - pytest.fail() - feat = None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT hstore_get_value(NULL, 'a')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) is None if ( ogr.GetGEOSVersionMajor() * 10000 @@ -1318,30 +1386,29 @@ def test_ogr_gpkg_15(gpkg_ds): + ogr.GetGEOSVersionMicro() >= 30800 ): - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_MakeValid(NULL)") - feat = sql_lyr.GetNextFeature() - assert feat.GetGeometryRef() is None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_MakeValid(NULL)") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_MakeValid('invalid')") - feat = sql_lyr.GetNextFeature() - assert feat.GetGeometryRef() is None - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT ST_MakeValid('invalid')") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetGeometryRef() is None - sql_lyr = gpkg_ds.ExecuteSQL("SELECT ST_MakeValid(geom) FROM tbl_linestring") - feat = sql_lyr.GetNextFeature() - if feat.GetGeometryRef().ExportToWkt() != "LINESTRING (5 5,10 5,10 10,5 10)": - feat.DumpReadable() - pytest.fail() - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL( + "SELECT ST_MakeValid(geom) FROM tbl_linestring" + ) as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert ( + feat.GetGeometryRef().ExportToWkt() + == "LINESTRING (5 5,10 5,10 10,5 10)" + ) if _has_spatialite_4_3_or_later(gpkg_ds): - sql_lyr = gpkg_ds.ExecuteSQL( + with gpkg_ds.ExecuteSQL( "SELECT ST_Buffer(geom, 1e-10) FROM tbl_linestring" - ) - assert sql_lyr.GetGeomType() == ogr.wkbPolygon - assert sql_lyr.GetSpatialRef().ExportToWkt().find("32631") >= 0 - gpkg_ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetGeomType() == ogr.wkbPolygon + assert sql_lyr.GetSpatialRef().ExportToWkt().find("32631") >= 0 ############################################################################### @@ -1358,19 +1425,15 @@ def test_ogr_gpkg_SetSRID(tmp_vsimem): lyr.CreateFeature(f) for srid in (32631, 0, -1, 12345678): - sql_lyr = ds.ExecuteSQL("SELECT ST_SRID(SetSRID(geom, %d)) FROM foo" % srid) - f = sql_lyr.GetNextFeature() - try: + with ds.ExecuteSQL( + "SELECT ST_SRID(SetSRID(geom, %d)) FROM foo" % srid + ) as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) == srid, srid - finally: - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL("SELECT ST_SRID(SetSRID(NULL, 32631)) FROM foo") - f = sql_lyr.GetNextFeature() - try: + with ds.ExecuteSQL("SELECT ST_SRID(SetSRID(NULL, 32631)) FROM foo") as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) is None - finally: - ds.ReleaseResultSet(sql_lyr) ds = None @@ -1393,7 +1456,7 @@ def test_ogr_gpkg_ST_EnvIntersects(tmp_vsimem): f.SetGeometry(ogr.CreateGeometryFromWkt("LINESTRING(5 6,7 8)")) lyr.CreateFeature(f) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT ST_EnvIntersects(geom, 0, 0, 0.99, 100)," + " ST_EnvIntersects(geom, 0, 4.01, 100, 100)," + " ST_EnvIntersects(geom, 3.01, 0, 100, 100)," @@ -1403,9 +1466,8 @@ def test_ogr_gpkg_ST_EnvIntersects(tmp_vsimem): + " ST_EnvIntersects(geom, 2.99, 3.99, 3.01, 4.01)," + " ST_EnvIntersects(geom, 2.99, 1.99, 3.01, 2.01)" + " FROM foo WHERE fid = 1" - ) - f = sql_lyr.GetNextFeature() - try: + ) as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) == 0 assert f.GetField(1) == 0 assert f.GetField(2) == 0 @@ -1414,35 +1476,24 @@ def test_ogr_gpkg_ST_EnvIntersects(tmp_vsimem): assert f.GetField(5) == 1 assert f.GetField(6) == 1 assert f.GetField(7) == 1 - finally: - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT ST_EnvIntersects(a.geom, b.geom) FROM foo a, foo b WHERE a.fid = 1 AND b.fid = 1" - ) - f = sql_lyr.GetNextFeature() - try: + ) as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) == 1 - finally: - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT ST_EnvIntersects(a.geom, b.geom) FROM foo a, foo b WHERE a.fid = 1 AND b.fid = 2" - ) - f = sql_lyr.GetNextFeature() - try: + ) as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) == 0 - finally: - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT ST_EnvIntersects(a.geom, b.geom) FROM foo a, foo b WHERE a.fid = 2 AND b.fid = 1" - ) - f = sql_lyr.GetNextFeature() - try: + ) as sql_lyr: + f = sql_lyr.GetNextFeature() assert f.GetField(0) == 0 - finally: - ds.ReleaseResultSet(sql_lyr) ds = None @@ -1575,10 +1626,9 @@ def test_ogr_gpkg_16b(tmp_vsimem): def test_ogr_gpkg_17(tmp_vsimem): ds = gdaltest.gpkg_dr.CreateDataSource(tmp_vsimem / "ogr_gpkg_17.gpkg") - sql_lyr = ds.ExecuteSQL("SELECT ogr_version()", dialect="INDIRECT_SQLITE") - f = sql_lyr.GetNextFeature() - assert f is not None - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT ogr_version()", dialect="INDIRECT_SQLITE") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f is not None ds = None @@ -1610,11 +1660,10 @@ def test_ogr_gpkg_18(tmp_vsimem, tmp_path): g = f.GetGeometryRef() assert g.GetGeometryType() == ogr.wkbCircularString - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_extensions WHERE table_name = 'wkbCircularString' AND extension_name = 'gpkg_geom_CIRCULARSTRING'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None @@ -1630,11 +1679,10 @@ def test_ogr_gpkg_18a(tmp_vsimem): lyr.CreateFeature(f) f = None - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_extensions WHERE table_name = 'test' AND extension_name = 'gpkg_geom_CIRCULARSTRING'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None @@ -1670,11 +1718,10 @@ def test_ogr_gpkg_18b(tmp_vsimem, tmp_path): with gdal.quiet_errors(): # Warning 1: Registering non-standard gpkg_geom_TRIANGLE extension ds.FlushCache() - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_extensions WHERE table_name = 'test' AND extension_name = 'gpkg_geom_TRIANGLE'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None if has_validate(): @@ -1695,11 +1742,10 @@ def test_ogr_gpkg_18c(tmp_vsimem): ) lyr.CreateFeature(f) f = None - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_extensions WHERE table_name = 'test' AND extension_name LIKE 'gpkg_geom_%'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None @@ -1752,11 +1798,10 @@ def test_ogr_gpkg_19(tmp_vsimem, tmp_path): ds = ogr.Open(fname) # Check that we don't create triggers - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE type = 'trigger' AND tbl_name IN ('gpkg_metadata', 'gpkg_metadata_reference')" - ) - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 lyr = ds.GetLayer("test_with_md") assert lyr.GetMetadataItem("IDENTIFIER") == "ident" @@ -1844,18 +1889,16 @@ def test_ogr_gpkg_20(tmp_vsimem, tmp_path): ds = ogr.Open(fname) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='my geogcs' AND srs_id = 100000 AND organization='MY_ORG' AND organization_coordsys_id=4326 AND description is NULL" - ) - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 1 - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='another geogcs' AND srs_id = 100001 AND organization='NONE' AND organization_coordsys_id=100001 AND description is NULL" - ) - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 1 lyr = ds.GetLayer("my_org_4326") @@ -1945,20 +1988,18 @@ def test_ogr_gpkg_srs_non_duplication_custom_crs(tmp_vsimem): lyr = ds.CreateLayer("test2", srs=srs) assert lyr - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 4 # srs_id 0, 1, 4326 + custom one - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='my custom geogcs'" - ) - assert sql_lyr.GetFeatureCount() == 1 - f = sql_lyr.GetNextFeature() - assert f["srs_id"] == 100000 - assert f["organization"] == "NONE" - assert f["organization_coordsys_id"] == 100000 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 + f = sql_lyr.GetNextFeature() + assert f["srs_id"] == 100000 + assert f["organization"] == "NONE" + assert f["organization_coordsys_id"] == 100000 # Test now transitionning to definition_12_063 / WKT2 database structure... srs_3d = osr.SpatialReference() @@ -1985,21 +2026,19 @@ def test_ogr_gpkg_srs_non_duplication_custom_crs(tmp_vsimem): lyr = ds.CreateLayer("test_3d_bis", srs=srs_3d) assert lyr - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='srs 3d'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 # Test again with SRS that can be represented in WKT1 lyr = ds.CreateLayer("test3", srs=srs) assert lyr - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='my custom geogcs'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None @@ -2051,15 +2090,14 @@ def test_ogr_gpkg_srs_non_consistent_with_official_definition(tmp_vsimem): == 'GEOGCS["my geogcs 4267",DATUM["WGS_1984",SPHEROID["my spheroid",1000,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4267"]]' ) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='my geogcs 4267'" - ) - assert sql_lyr.GetFeatureCount() == 1 - f = sql_lyr.GetNextFeature() - assert f["srs_id"] == 100000 - assert f["organization"] == "NONE" - assert f["organization_coordsys_id"] == 100000 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 + f = sql_lyr.GetNextFeature() + assert f["srs_id"] == 100000 + assert f["organization"] == "NONE" + assert f["organization_coordsys_id"] == 100000 lyr = ds.GetLayer("test_fake_4326") assert ( @@ -2067,28 +2105,25 @@ def test_ogr_gpkg_srs_non_consistent_with_official_definition(tmp_vsimem): == 'GEOGCS["my geogcs 4326",DATUM["WGS_1984",SPHEROID["my spheroid",1000,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]' ) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_spatial_ref_sys WHERE srs_name='my geogcs 4326'" - ) - assert sql_lyr.GetFeatureCount() == 1 - f = sql_lyr.GetNextFeature() - assert f["srs_id"] == 100001 - assert f["organization"] == "NONE" - assert f["organization_coordsys_id"] == 100001 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 + f = sql_lyr.GetNextFeature() + assert f["srs_id"] == 100001 + assert f["organization"] == "NONE" + assert f["organization_coordsys_id"] == 100001 - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") - fc_before = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") as sql_lyr: + fc_before = sql_lyr.GetFeatureCount() gdal.ErrorReset() gdal.ErrorReset() lyr = ds.CreateLayer("test_fake_4267_bis", srs=test_fake_4267) assert gdal.GetLastErrorMsg() == "" - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") - fc_after = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys") as sql_lyr: + fc_after = sql_lyr.GetFeatureCount() assert fc_before == fc_after ds = None @@ -2102,10 +2137,9 @@ def test_ogr_gpkg_write_srs_undefined_geographic(tmp_path): assert gpkg_ds is not None # Check initial default SRS entries in gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") - gpkg_spatial_ref_sys_total = sql_lyr.GetNextFeature().GetField(0) - assert gpkg_spatial_ref_sys_total == 3 # entries with SRS IDs: -1, 0, 4326 - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") as sql_lyr: + gpkg_spatial_ref_sys_total = sql_lyr.GetNextFeature().GetField(0) + assert gpkg_spatial_ref_sys_total == 3 # entries with SRS IDs: -1, 0, 4326 srs = osr.SpatialReference() srs.SetFromUserInput( @@ -2122,9 +2156,8 @@ def test_ogr_gpkg_write_srs_undefined_geographic(tmp_path): gpkg_ds = ogr.Open(fname) # Check no new SRS entries have been inserted into gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") - assert gpkg_spatial_ref_sys_total == sql_lyr.GetNextFeature().GetField(0) - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") as sql_lyr: + assert gpkg_spatial_ref_sys_total == sql_lyr.GetNextFeature().GetField(0) lyr = gpkg_ds.GetLayer(0) srs_wkt = lyr.GetSpatialRef().ExportToWkt() @@ -2142,10 +2175,9 @@ def test_ogr_gpkg_write_srs_undefined_Cartesian(tmp_path): assert gpkg_ds is not None # Check initial default SRS entries in gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") - gpkg_spatial_ref_sys_total = sql_lyr.GetNextFeature().GetField(0) - assert gpkg_spatial_ref_sys_total == 3 # SRS with IDs: -1, 0, 4326 - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") as sql_lyr: + gpkg_spatial_ref_sys_total = sql_lyr.GetNextFeature().GetField(0) + assert gpkg_spatial_ref_sys_total == 3 # SRS with IDs: -1, 0, 4326 srs = osr.SpatialReference() srs.SetFromUserInput('LOCAL_CS["Undefined Cartesian SRS"]') @@ -2160,9 +2192,8 @@ def test_ogr_gpkg_write_srs_undefined_Cartesian(tmp_path): gpkg_ds = ogr.Open(fname) # Check no new SRS entries have been inserted into gpkg_spatial_ref_sys - sql_lyr = gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") - assert gpkg_spatial_ref_sys_total == sql_lyr.GetNextFeature().GetField(0) - gpkg_ds.ReleaseResultSet(sql_lyr) + with gpkg_ds.ExecuteSQL("SELECT COUNT(*) FROM gpkg_spatial_ref_sys") as sql_lyr: + assert gpkg_spatial_ref_sys_total == sql_lyr.GetNextFeature().GetField(0) lyr = gpkg_ds.GetLayer(0) srs_wkt = lyr.GetSpatialRef().ExportToWkt() @@ -2513,38 +2544,40 @@ def test_ogr_gpkg_23(tmp_vsimem): field_defn = ogr.FieldDefn("field_nullable", ogr.OFTString) lyr.CreateField(field_defn) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_contents WHERE data_type = 'features'") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT * FROM gpkg_contents WHERE data_type = 'features'" + ) as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 2 - sql_lyr = ds.ExecuteSQL("SELECT 1 FROM sqlite_master WHERE name='gpkg_extensions'") - has_gpkg_extensions = sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT 1 FROM sqlite_master WHERE name='gpkg_extensions'" + ) as sql_lyr: + has_gpkg_extensions = sql_lyr.GetFeatureCount() == 1 assert not has_gpkg_extensions - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 2 field_defn = ogr.GeomFieldDefn("geomfield_not_nullable", ogr.wkbPoint) field_defn.SetNullable(0) lyr.CreateGeomField(field_defn) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_contents WHERE data_type = 'features'") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT * FROM gpkg_contents WHERE data_type = 'features'" + ) as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 3 - sql_lyr = ds.ExecuteSQL("SELECT 1 FROM sqlite_master WHERE name='gpkg_extensions'") - has_gpkg_extensions = sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT 1 FROM sqlite_master WHERE name='gpkg_extensions'" + ) as sql_lyr: + has_gpkg_extensions = sql_lyr.GetFeatureCount() == 1 assert not has_gpkg_extensions - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 3 f = ogr.Feature(lyr.GetLayerDefn()) @@ -3096,7 +3129,8 @@ def test_ogr_gpkg_26(tmp_vsimem): ret = lyr.CreateFeature(f) # ds.CommitTransaction() - ds.ReleaseResultSet(ds.ExecuteSQL("SELECT 1")) + with ds.ExecuteSQL("SELECT 1") as sql_lyr: + assert sql_lyr # ds = None # ds = ogr.Open('/vsimem/ogr_gpkg_26.gpkg', update = 1) # lyr = ds.GetLayerByName('test3') @@ -3133,12 +3167,9 @@ def test_ogr_gpkg_27(tmp_vsimem): f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt("POINT (2 49)")) lyr.CreateFeature(f) - sql_lyr = ds.ExecuteSQL("SELECT GeomFromGPB(geom) FROM test") - f = sql_lyr.GetNextFeature() - if f.GetGeometryRef().ExportToWkt() != "POINT (2 49)": - f.DumpReadable() - pytest.fail() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT GeomFromGPB(geom) FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetGeometryRef().ExportToWkt() == "POINT (2 49)" ds = None @@ -3305,17 +3336,16 @@ def test_ogr_gpkg_32(tmp_vsimem, tmp_path): ds = ogr.Open(fname) assert ds.GetLayerCount() == 1 - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_contents") - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL("SELECT * FROM gpkg_contents") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 + + with ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 + + with ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE name = 'gpkg_extensions'" - ) - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 ds = None assert validate(fname, tmpdir=tmp_path), "validation failed" @@ -3335,11 +3365,10 @@ def test_ogr_gpkg_33(tmp_vsimem): ds = None ds = ogr.Open(fname) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_contents WHERE last_change = '2000-01-01T:00:00:00.000Z'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 ds = None @@ -3607,13 +3636,11 @@ def test_ogr_gpkg_35(tmp_vsimem, tmp_path): # Try on read-only dataset ds = ogr.Open(dbname) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_metadata WHERE id = 1") - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_metadata WHERE id = 1") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_metadata WHERE id = 2") - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_metadata WHERE id = 2") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 lyr = ds.GetLayerByName("test_nonspatial") assert lyr.GetMetadataItem("FOO") == "BAR" @@ -3671,11 +3698,10 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): ds.ExecuteSQL("CREATE INDEX my_idx ON test(foo)") # gpkg_data_columns should have been created because of AlternativeName set on field - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'foo'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 # Metadata lyr.SetMetadataItem("FOO", "BAR") @@ -3726,11 +3752,10 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): new_field_defn.SetAlternativeName("alt name") assert lyr.AlterFieldDefn(0, new_field_defn, ogr.ALTER_ALL_FLAG) == 0 - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'bar'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 # Violation of not-null constraint new_field_defn = ogr.FieldDefn("baz", ogr.OFTString) @@ -3749,11 +3774,10 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): pytest.fail() f = None - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'bar'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 # Just change the name, and run it outside an existing transaction lyr.StartTransaction() @@ -3761,11 +3785,10 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): assert lyr.AlterFieldDefn(0, new_field_defn, ogr.ALTER_NAME_FLAG) == 0 lyr.CommitTransaction() - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'baw2'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 lyr.ResetReading() f = lyr.GetNextFeature() @@ -3802,11 +3825,10 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): f = None # Check that index has been recreated - sql_lyr = ds.ExecuteSQL("SELECT * FROM sqlite_master WHERE name = 'my_idx'") - f = sql_lyr.GetNextFeature() - assert f is not None - f = None - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM sqlite_master WHERE name = 'my_idx'") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f is not None + f = None ds.ExecuteSQL("VACUUM") @@ -3817,17 +3839,15 @@ def test_ogr_gpkg_36(tmp_vsimem, tmp_path): # Try on read-only dataset ds = ogr.Open(dbname) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'baw'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_metadata_reference WHERE table_name = 'test' AND column_name = 'baw'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 lyr = ds.GetLayer(0) with gdal.quiet_errors(): @@ -3877,21 +3897,19 @@ def test_ogr_gpkg_36_alter_comment_after_alternative_name(tmp_vsimem, tmp_path): assert lyr.AlterFieldDefn(0, new_field_defn, ogr.ALTER_ALTERNATIVE_NAME_FLAG) == 0 # gpkg_data_columns should have been created because of AlternativeName set on field - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'foo'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 new_field_defn = ogr.FieldDefn(field.GetName(), field.GetType()) new_field_defn.SetComment("alt comment") assert lyr.AlterFieldDefn(0, new_field_defn, ogr.ALTER_COMMENT_FLAG) == 0 - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_data_columns WHERE table_name = 'test' AND column_name = 'foo'" - ) - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 assert lyr.GetLayerDefn().GetFieldDefn(0).GetAlternativeName() == "alt name" assert lyr.GetLayerDefn().GetFieldDefn(0).GetComment() == "alt comment" @@ -3974,11 +3992,10 @@ def test_ogr_gpkg_37(tmp_vsimem): pytest.fail() # Check that index has been recreated - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE name = 'my_idx_foo' OR name = 'my_idx_bar'" - ) - assert sql_lyr.GetFeatureCount() == 2 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 2 ds = None @@ -4020,12 +4037,14 @@ def test_ogr_gpkg_38(tmp_vsimem, spatial_index): # Test that we can compute the extent of a layer that has none registered in gpkg_contents extent = lyr.GetExtent(force=1) assert extent == (1, 3, 2, 4) - sql_lyr = ds.ExecuteSQL("SELECT min_x, min_y, max_x, max_y FROM gpkg_contents") - f = sql_lyr.GetNextFeature() - if f["min_x"] != 1 or f["min_y"] != 2 or f["max_x"] != 3 or f["max_y"] != 4: - f.DumpReadable() - pytest.fail() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT min_x, min_y, max_x, max_y FROM gpkg_contents" + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + if f["min_x"] != 1 or f["min_y"] != 2 or f["max_x"] != 3 or f["max_y"] != 4: + f.DumpReadable() + pytest.fail() + extent = lyr.GetExtent(force=0) assert extent == (1, 3, 2, 4) @@ -4122,17 +4141,17 @@ def test_ogr_gpkg_40(tmp_vsimem, tmp_path): ds = ogr.Open(dbname) assert ds.GetLayerCount() == 1 - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_contents") - assert sql_lyr.GetFeatureCount() == 1 - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL("SELECT * FROM gpkg_contents") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 1 + + with ds.ExecuteSQL("SELECT * FROM gpkg_geometry_columns") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 + + with ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE name = 'gpkg_extensions'" - ) - assert sql_lyr.GetFeatureCount() == 0 - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + assert sql_lyr.GetFeatureCount() == 0 + ds = None assert validate(dbname, tmpdir=tmp_path), "validation failed" @@ -4178,25 +4197,21 @@ def test_ogr_gpkg_41(tmp_vsimem): def foo_has_trigger(ds): - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT COUNT(*) FROM sqlite_master WHERE name = 'trigger_insert_feature_count_foo'", dialect="DEBUG", - ) - f = sql_lyr.GetNextFeature() - has_trigger = f.GetField(0) == 1 - f = None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + has_trigger = f.GetField(0) == 1 return has_trigger def get_feature_count_from_gpkg_contents(ds): - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT feature_count FROM gpkg_ogr_contents", dialect="DEBUG" - ) - f = sql_lyr.GetNextFeature() - val = f.GetField(0) - f = None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + val = f.GetField(0) return val @@ -4300,24 +4315,22 @@ def test_ogr_gpkg_42(tmp_vsimem): ds = None ds = ogr.Open(dbname, update=1) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT feature_count FROM gpkg_ogr_contents WHERE table_name = 'bar'", dialect="DEBUG", - ) - f = sql_lyr.GetNextFeature() - val = f.GetField(0) - f = None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + val = f.GetField(0) + f = None assert val == 5000 # Test layer deletion ds.DeleteLayer(0) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT feature_count FROM gpkg_ogr_contents", dialect="DEBUG" - ) - f = sql_lyr.GetNextFeature() - assert f is None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f is None ds = None # Test without feature_count column @@ -4335,9 +4348,8 @@ def test_ogr_gpkg_42(tmp_vsimem): ds = ogr.Open(dbname, update=1) # Check that feature_count column is missing - sql_lyr = ds.ExecuteSQL("PRAGMA table_info(gpkg_contents)") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("PRAGMA table_info(gpkg_contents)") as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 10 assert not foo_has_trigger(ds) @@ -4589,22 +4601,23 @@ def test_ogr_gpkg_46(tmp_vsimem): # Operations not valid on a view with gdal.quiet_errors(): - ds.ReleaseResultSet( - ds.ExecuteSQL("SELECT CreateSpatialIndex('my_view', 'my_geom')") - ) - ds.ReleaseResultSet( - ds.ExecuteSQL("SELECT DisableSpatialIndex('my_view', 'my_geom')") - ) + with ds.ExecuteSQL( + "SELECT CreateSpatialIndex('my_view', 'my_geom')" + ) as sql_lyr: + pass + with ds.ExecuteSQL( + "SELECT DisableSpatialIndex('my_view', 'my_geom')" + ) as sql_lyr: + pass lyr.AlterFieldDefn(0, lyr.GetLayerDefn().GetFieldDefn(0), ogr.ALTER_ALL_FLAG) lyr.DeleteField(0) lyr.ReorderFields([0]) lyr.CreateField(ogr.FieldDefn("bar")) # Check if spatial index is recognized - sql_lyr = ds.ExecuteSQL("SELECT HasSpatialIndex('my_view', 'my_geom')") - f = sql_lyr.GetNextFeature() - has_spatial_index = f.GetField(0) == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT HasSpatialIndex('my_view', 'my_geom')") as sql_lyr: + f = sql_lyr.GetNextFeature() + has_spatial_index = f.GetField(0) == 1 if not has_spatial_index: ds = None pytest.skip("SQLite likely built without SQLITE_HAS_COLUMN_METADATA") @@ -5105,15 +5118,14 @@ def test_ogr_gpkg_56(tmp_vsimem): ds = gdal.VectorTranslate( tmp_vsimem / "ogr_gpkg_56.gpkg", "data/poly.shp", format="GPKG" ) - lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "select a.fid as fid1, b.fid as fid2 from poly a, poly b order by fid1, fid2" - ) - lyr.GetNextFeature() - f = lyr.GetNextFeature() - if f.GetField("fid1") != 1 or f.GetField("fid2") != 2: - f.DumpReadable() - pytest.fail() - ds.ReleaseResultSet(lyr) + ) as lyr: + lyr.GetNextFeature() + f = lyr.GetNextFeature() + if f.GetField("fid1") != 1 or f.GetField("fid2") != 2: + f.DumpReadable() + pytest.fail() ds = None @@ -5328,10 +5340,9 @@ def test_ogr_gpkg_58(tmp_vsimem): ) ds = ogr.Open(out_filename) - sql_lyr = ds.ExecuteSQL("SELECT HasSpatialIndex('poly', 'geom')") - f = sql_lyr.GetNextFeature() - assert f.GetField(0) == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT HasSpatialIndex('poly', 'geom')") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 1 ds = None gdal.Unlink(out_filename) @@ -5352,10 +5363,9 @@ def test_ogr_gpkg_59(tmp_vsimem): ) ds = ogr.Open(out_filename, update=1) - sql_lyr = ds.ExecuteSQL("SELECT CreateSpatialIndex('poly', 'geom')") - f = sql_lyr.GetNextFeature() - assert f.GetField(0) == 1 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT CreateSpatialIndex('poly', 'geom')") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 1 ds = None @@ -5435,10 +5445,9 @@ def test_ogr_gpkg_wal(tmp_path): def test_ogr_gpkg_nolock(tmp_path): def get_nolock(ds): - sql_lyr = ds.ExecuteSQL("SELECT nolock", dialect="DEBUG") - f = sql_lyr.GetNextFeature() - res = True if f[0] == 1 else False - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT nolock", dialect="DEBUG") as sql_lyr: + f = sql_lyr.GetNextFeature() + res = True if f[0] == 1 else False return res # needs to be a real file @@ -5482,7 +5491,8 @@ def get_nolock(ds): # Now turn on WAL ds = ogr.Open(filename, update=1) - ds.ReleaseResultSet(ds.ExecuteSQL("PRAGMA journal_mode = WAL")) + with ds.ExecuteSQL("PRAGMA journal_mode = WAL") as sql_lyr: + assert sql_lyr ds = None # Lockless mode should NOT be honored by GDAL on a WAL enabled file @@ -5516,11 +5526,10 @@ def test_ogr_gpkg_test_ogrsf(gpkg_ds): dbname = gpkg_ds.GetDescription() # Do integrity check first - gpkg_ds = ogr.Open(dbname) - sql_lyr = gpkg_ds.ExecuteSQL("PRAGMA integrity_check") - feat = sql_lyr.GetNextFeature() - assert feat.GetField(0) == "ok", "integrity check failed" - gpkg_ds.ReleaseResultSet(sql_lyr) + gpkg_ds = gdaltest.reopen(gpkg_ds) + with gpkg_ds.ExecuteSQL("PRAGMA integrity_check") as sql_lyr: + feat = sql_lyr.GetNextFeature() + assert feat.GetField(0) == "ok", "integrity check failed" import test_cli_utilities @@ -5561,7 +5570,8 @@ def test_ogr_gpkg_json(tmp_vsimem, tmp_path): lyr.CreateField(fld_defn) assert lyr.GetLayerDefn().GetFieldDefn(0).GetSubType() == ogr.OFSTJSON - ds.ReleaseResultSet(ds.ExecuteSQL("SELECT 1 FROM test")) # will crystalize + with ds.ExecuteSQL("SELECT 1 FROM test") as sql_lyr: # will crystalize + pass fld_defn = ogr.FieldDefn("test2_json", ogr.OFTString) fld_defn.SetSubType(ogr.OFSTJSON) @@ -5621,9 +5631,10 @@ def test_ogr_gpkg_json(tmp_vsimem, tmp_path): == ogr.OFSTJSON ) - sql_lyr = ds.ExecuteSQL("SELECT 1 FROM gpkg_data_columns WHERE table_name = 'test'") - fc = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL( + "SELECT 1 FROM gpkg_data_columns WHERE table_name = 'test'" + ) as sql_lyr: + fc = sql_lyr.GetFeatureCount() assert fc == 1 ds = None @@ -5735,10 +5746,9 @@ def test_ogr_gpkg_mixed_dimensionality_unknown_layer_geometry_type( lyr = ds.GetLayer(0) assert lyr.GetGeomType() == ogr.wkbUnknown - sql_lyr = ds.ExecuteSQL("SELECT z FROM gpkg_geometry_columns") - f = sql_lyr.GetNextFeature() - assert f.GetField(0) == 2 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT z FROM gpkg_geometry_columns") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 2 ds = None @@ -5805,29 +5815,26 @@ def test_ogr_gpkg_fixup_wrong_rtree_trigger(tmp_vsimem): # Open in read-only mode ds = ogr.Open(filename) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = 'rtree_test-with-dash_geometry_update3'" - ) - f = sql_lyr.GetNextFeature() - sql = f["sql"] - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + sql = f["sql"] ds = None assert sql == wrong_trigger # Open in update mode ds = ogr.Open(filename, update=1) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = 'rtree_test-with-dash_geometry_update3'" - ) - f = sql_lyr.GetNextFeature() - sql = f["sql"] - ds.ReleaseResultSet(sql_lyr) - sql_lyr = ds.ExecuteSQL( + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + sql = f["sql"] + with ds.ExecuteSQL( "SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = 'rtree_test2_geometry_update3'" - ) - f = sql_lyr.GetNextFeature() - sql2 = f["sql"] - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + sql2 = f["sql"] ds = None gdal.Unlink(filename) @@ -5854,9 +5861,8 @@ def test_ogr_gpkg_prelude_statements(tmp_vsimem): f"PRELUDE_STATEMENTS=ATTACH DATABASE '{tmp_vsimem}/test.gpkg' AS other" ], ) - sql_lyr = ds.ExecuteSQL("SELECT * FROM poly JOIN other.poly USING (eas_id)") - assert sql_lyr.GetFeatureCount() == 10 - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM poly JOIN other.poly USING (eas_id)") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 10 ############################################################################### @@ -5888,11 +5894,10 @@ def test_ogr_gpkg_datetime_timezones(tmp_vsimem): f = lyr.GetNextFeature() assert f.GetField("dt") == "2019/12/31 23:34:56.789+00" - sql_lyr = ds.ExecuteSQL("SELECT dt || '' FROM test") - f = sql_lyr.GetNextFeature() - # check that milliseconds are written to be strictly compliant with the GPKG spec - assert f.GetField(0) == "2020-01-01T01:34:56.000Z" - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT dt || '' FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + # check that milliseconds are written to be strictly compliant with the GPKG spec + assert f.GetField(0) == "2020-01-01T01:34:56.000Z" ds = None @@ -5925,7 +5930,7 @@ def abortAfterDelay(): SELECT i FROM r WHERE i = 1;""" with gdal.quiet_errors(): - ds.ExecuteSQL(sql) + assert ds.ExecuteSQL(sql) is None end = time.time() assert int(end - start) < 2 @@ -5944,7 +5949,7 @@ def abortAfterDelay2(): # Long running query with gdal.quiet_errors(): - ds2.ExecuteSQL(sql) + assert ds2.ExecuteSQL(sql) is None end = time.time() assert int(end - start) < 2 @@ -5972,15 +5977,14 @@ def test_ogr_gpkg_st_transform_no_record_spatial_ref_sys(tmp_vsimem): ds = None pytest.skip("Spatialite missing or too old") - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT ST_Transform(SetSRID(geom, 32631), 32731) FROM test" - ) - # Fails on a number of configs - # assert sql_lyr.GetSpatialRef().GetAuthorityCode(None) == '32731' - f = sql_lyr.GetNextFeature() - assert f.GetGeometryRef().ExportToWkt() == "POINT (500000 10000000)" - f = None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + # Fails on a number of configs + # assert sql_lyr.GetSpatialRef().GetAuthorityCode(None) == '32731' + f = sql_lyr.GetNextFeature() + assert f.GetGeometryRef().ExportToWkt() == "POINT (500000 10000000)" + f = None ds = None @@ -5991,12 +5995,11 @@ def test_ogr_gpkg_st_transform_no_record_spatial_ref_sys(tmp_vsimem): def test_ogr_gpkg_deferred_spi_creation(tmp_vsimem): def has_spi(ds): - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT 1 FROM sqlite_master WHERE name = 'rtree_test_geom'", dialect="DEBUG", - ) - res = sql_lyr.GetNextFeature() is not None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + res = sql_lyr.GetNextFeature() is not None return res ds = ogr.GetDriverByName("GPKG").CreateDataSource(tmp_vsimem / "test.gpkg") @@ -6024,7 +6027,8 @@ def has_spi(ds): assert lyr.DeleteField(0) == ogr.OGRERR_NONE assert not has_spi(ds) - ds.ReleaseResultSet(ds.ExecuteSQL("SELECT 1")) + with ds.ExecuteSQL("SELECT 1") as sql_lyr: + assert sql_lyr assert has_spi(ds) # GetNextFeature() with spatial filter should cause SPI creation @@ -6055,12 +6059,11 @@ def has_spi(ds): @pytest.mark.parametrize("gpkg_version", ["1.2", "1.4"]) def test_ogr_gpkg_deferred_spi_update(tmp_vsimem, gpkg_version): def has_spi_triggers(ds): - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM sqlite_master WHERE type = 'trigger' AND name LIKE 'rtree_test_geom%'", dialect="DEBUG", - ) - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + res = sql_lyr.GetFeatureCount() return res == 6 or res == 7 filename = tmp_vsimem / "test.gpkg" @@ -6092,17 +6095,15 @@ def has_spi_triggers(ds): lyr.CreateFeature(f) assert not has_spi_triggers(ds) - sql_lyr = ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") as sql_lyr: + res = sql_lyr.GetFeatureCount() assert res == 2 ds.CommitTransaction() assert has_spi_triggers(ds) - sql_lyr = ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") as sql_lyr: + res = sql_lyr.GetFeatureCount() assert res == 3 ds = None @@ -6129,17 +6130,15 @@ def has_spi_triggers(ds): lyr.CreateFeature(f) assert not has_spi_triggers(ds) - sql_lyr = ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") as sql_lyr: + res = sql_lyr.GetFeatureCount() assert res == 1 ds.RollbackTransaction() assert has_spi_triggers(ds) - sql_lyr = ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM rtree_test_geom", dialect="DEBUG") as sql_lyr: + res = sql_lyr.GetFeatureCount() assert res == 0 ds = None @@ -6403,9 +6402,8 @@ def test_ogr_gpkg_field_domains(tmp_vsimem, tmp_path): # Test read support ds = gdal.OpenEx(filename, gdal.OF_VECTOR) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_data_column_constraints") - assert sql_lyr is not None - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT * FROM gpkg_data_column_constraints") as sql_lyr: + assert sql_lyr assert set(ds.GetFieldDomainNames()) == { "enum_domain", @@ -6519,11 +6517,11 @@ def test_ogr_gpkg_field_domains(tmp_vsimem, tmp_path): assert fld_defn.GetDomainName() == "range_domain_int" if gdal.GetDriverByName("GPKG").GetMetadataItem("SQLITE_HAS_COLUMN_METADATA"): - sql_lyr = ds.ExecuteSQL("SELECT with_range_domain_int FROM test") - assert ( - sql_lyr.GetLayerDefn().GetFieldDefn(0).GetDomainName() == "range_domain_int" - ) - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL("SELECT with_range_domain_int FROM test") as sql_lyr: + assert ( + sql_lyr.GetLayerDefn().GetFieldDefn(0).GetDomainName() + == "range_domain_int" + ) ds = None @@ -6941,13 +6939,12 @@ def test_ogr_gpkg_fixup_wrong_mr_column_name_update_trigger(tmp_vsimem): # Open in update mode ds = ogr.Open(filename, update=1) - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT sql FROM sqlite_master WHERE type = 'trigger' " + "AND name = 'gpkg_metadata_reference_column_name_update'" - ) - f = sql_lyr.GetNextFeature() - sql = f["sql"] - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + sql = f["sql"] ds = None assert "column_nameIS" not in sql @@ -6988,47 +6985,46 @@ def test_ogr_gpkg_crs_coordinate_epoch(tmp_vsimem, tmp_path): ds = ogr.Open(filename) - sql_lyr = ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys ORDER BY srs_id") - assert sql_lyr.GetFeatureCount() == 7 + with ds.ExecuteSQL("SELECT * FROM gpkg_spatial_ref_sys ORDER BY srs_id") as sql_lyr: + assert sql_lyr.GetFeatureCount() == 7 - sql_lyr.GetNextFeature() - sql_lyr.GetNextFeature() + sql_lyr.GetNextFeature() + sql_lyr.GetNextFeature() - f = sql_lyr.GetNextFeature() - assert f - assert f["srs_id"] == 4258 - assert f["organization"] == "EPSG" - assert f["organization_coordsys_id"] == 4258 - assert f["epoch"] is None + f = sql_lyr.GetNextFeature() + assert f + assert f["srs_id"] == 4258 + assert f["organization"] == "EPSG" + assert f["organization_coordsys_id"] == 4258 + assert f["epoch"] is None - f = sql_lyr.GetNextFeature() - assert f - assert f["srs_id"] == 4326 - assert f["organization"] == "EPSG" - assert f["organization_coordsys_id"] == 4326 - assert f["epoch"] is None + f = sql_lyr.GetNextFeature() + assert f + assert f["srs_id"] == 4326 + assert f["organization"] == "EPSG" + assert f["organization_coordsys_id"] == 4326 + assert f["epoch"] is None - f = sql_lyr.GetNextFeature() - assert f - assert f["srs_id"] == 100000 - assert f["organization"] == "NONE" - assert f["organization_coordsys_id"] == 100000 - assert f["epoch"] == 2021.3 + f = sql_lyr.GetNextFeature() + assert f + assert f["srs_id"] == 100000 + assert f["organization"] == "NONE" + assert f["organization_coordsys_id"] == 100000 + assert f["epoch"] == 2021.3 - f = sql_lyr.GetNextFeature() - assert f - assert f["srs_id"] == 100001 - assert f["organization"] == "EPSG" - assert f["organization_coordsys_id"] == 7665 - assert f["epoch"] == 2021.3 + f = sql_lyr.GetNextFeature() + assert f + assert f["srs_id"] == 100001 + assert f["organization"] == "EPSG" + assert f["organization_coordsys_id"] == 7665 + assert f["epoch"] == 2021.3 - f = sql_lyr.GetNextFeature() - assert f - assert f["srs_id"] == 100002 - assert f["organization"] == "EPSG" - assert f["organization_coordsys_id"] == 7665 - assert f["epoch"] == 2021.2 - ds.ReleaseResultSet(sql_lyr) + f = sql_lyr.GetNextFeature() + assert f + assert f["srs_id"] == 100002 + assert f["organization"] == "EPSG" + assert f["organization_coordsys_id"] == 7665 + assert f["epoch"] == 2021.2 lyr = ds.GetLayerByName("lyr_with_coordinate_epoch_unknown_srs") srs = lyr.GetSpatialRef() @@ -7200,12 +7196,11 @@ def test_ogr_gpkg_relations(tmp_vsimem, tmp_path): ds = gdal.OpenEx(filename, gdal.OF_VECTOR | gdal.OF_UPDATE) ds.ExecuteSQL("DELLAYER:a_renamed") - sql_lyr = ds.ExecuteSQL( + with ds.ExecuteSQL( "SELECT * FROM gpkg_extensions WHERE extension_name IN ('related_tables', 'gpkg_related_tables')" - ) - f = sql_lyr.GetNextFeature() - assert f is None - ds.ReleaseResultSet(sql_lyr) + ) as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f is None assert ds.GetRelationshipNames() is None ds = None @@ -7341,9 +7336,8 @@ def clone_relationship(relationship): ds = gdaltest.gpkg_dr.CreateDataSource(filename) def get_query_row_count(query): - sql_lyr = ds.ExecuteSQL(query) - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL(query) as sql_lyr: + res = sql_lyr.GetFeatureCount() return res relationship = gdal.Relationship( @@ -7861,9 +7855,8 @@ def test_ogr_gpkg_add_relationship_complex_names(tmp_vsimem, tmp_path): ds = gdaltest.gpkg_dr.CreateDataSource(filename) def get_query_row_count(query): - sql_lyr = ds.ExecuteSQL(query) - res = sql_lyr.GetFeatureCount() - ds.ReleaseResultSet(sql_lyr) + with ds.ExecuteSQL(query) as sql_lyr: + res = sql_lyr.GetFeatureCount() return res relationship = gdal.Relationship( @@ -8630,7 +8623,8 @@ def test_ogr_gpkg_immutable(tmp_path): tmp_path / "read_only_test_ogr_gpkg_immutable/test.gpkg" ) ds.CreateLayer("foo") - ds.ExecuteSQL("PRAGMA journal_mode = WAL") + with ds.ExecuteSQL("PRAGMA journal_mode = WAL") as sql_lyr: + assert sql_lyr ds = None # Turn directory in read-only mode @@ -10138,7 +10132,15 @@ def test_ogr_gpkg_arrow_stream_huge_array(tmp_vsimem, too_big_field): batch_count += 1 for fid in batch[lyr.GetFIDColumn()]: got_fids.append(fid) - assert got_fids == [i + 1 for i in range(50)] + # This test fails randomly on CI when too_big_field = "huge_string" + # with values of got_fids starting at 25 being corrupted. + # Cf https://github.com/OSGeo/gdal/actions/runs/11917921824/job/33214164831?pr=11301 + expected_fids = [i + 1 for i in range(50)] + if "CI" in os.environ and got_fids != expected_fids: + pytest.xfail( + f"Random failure on CI occurred in test_ogr_gpkg_arrow_stream_huge_array[{too_big_field}]. Expected {expected_fids}, got {got_fids}" + ) + assert got_fids == expected_fids assert batch_count == (25 if too_big_field == "geometry" else 21), lyr_name del stream @@ -10198,12 +10200,12 @@ def test_ogr_gpkg_like_utf8(tmp_vsimem): ) as sql_lyr: assert sql_lyr.GetFeatureCount() == 0 - ds.ExecuteSQL("PRAGMA case_sensitive_like = 1") + assert ds.ExecuteSQL("PRAGMA case_sensitive_like = 1") is None with ds.ExecuteSQL("SELECT * FROM test WHERE 'e' LIKE 'E'") as sql_lyr: assert sql_lyr.GetFeatureCount() == 0 - ds.ExecuteSQL("PRAGMA case_sensitive_like = 0") + assert ds.ExecuteSQL("PRAGMA case_sensitive_like = 0") is None with ds.ExecuteSQL("SELECT * FROM test WHERE 'e' LIKE 'E'") as sql_lyr: assert sql_lyr.GetFeatureCount() == 1 @@ -10623,6 +10625,21 @@ def test_ogr_gpkg_ST_Length_on_ellipsoid(tmp_vsimem): assert f[0] is None +############################################################################### +# Test that CreateCopy() works on a vector dataset +# Test fix for https://github.com/OSGeo/gdal/issues/11282 + + +@gdaltest.enable_exceptions() +@pytest.mark.usefixtures("tpoly") +def test_ogr_gpkg_CreateCopy(gpkg_ds, tmp_vsimem): + + tmpfilename = tmp_vsimem / "test_ogr_gpkg_CreateCopy.gpkg" + + out_ds = gdal.GetDriverByName("GPKG").CreateCopy(tmpfilename, gpkg_ds) + assert out_ds.GetLayerCount() == 1 + + ############################################################################### # Test LAUNDER=YES layer creation option @@ -10680,3 +10697,137 @@ def test_gpkg_rename_hidden_table(tmp_vsimem): gdal.VSIFCloseL(f) assert "hidden_foo_table" not in content + + +############################################################################### +# Test creating duplicate field names + + +@gdaltest.enable_exceptions() +def test_gpkg_create_duplicate_field_names(tmp_vsimem): + + filename = str(tmp_vsimem / "test_gpkg_create_duplicate_field_names.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test") + lyr.CreateField(ogr.FieldDefn("foo")) + with pytest.raises( + Exception, match="A field with the same name already exists" + ): + lyr.CreateField(ogr.FieldDefn("foo")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 + with pytest.raises( + Exception, match="A field with the same name already exists" + ): + lyr.CreateField(ogr.FieldDefn("FOO")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 + with pytest.raises( + Exception, match="It has the same name as the geometry field" + ): + lyr.CreateField(ogr.FieldDefn("geom")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 + + +############################################################################### +# Test creating more than 2000 fields + + +@gdaltest.enable_exceptions() +def test_gpkg_create_more_than_2000_fields(tmp_vsimem): + + filename = str(tmp_vsimem / "test_gpkg_create_more_than_2000_fields.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test") + + for i in range(2000 - 2): + lyr.CreateField(ogr.FieldDefn(f"foo{i}")) + with pytest.raises(Exception, match="Limit of 2000 columns reached"): + lyr.CreateField(ogr.FieldDefn("foo")) + assert lyr.GetLayerDefn().GetFieldCount() == 2000 - 2 + + +############################################################################### +# Test that secure_delete is turned on + + +@gdaltest.enable_exceptions() +def test_gpkg_secure_delete(tmp_vsimem): + + filename = str(tmp_vsimem / "secure_delete.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + + with ds.ExecuteSQL("PRAGMA secure_delete") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 1 + + lyr = ds.CreateLayer("test") + lyr.CreateField(ogr.FieldDefn("foo")) + f = ogr.Feature(lyr.GetLayerDefn()) + f["foo"] = "very_secret" + lyr.CreateFeature(f) + + f = gdal.VSIFOpenL(filename, "rb") + data = gdal.VSIFReadL(1, 100000, f) + gdal.VSIFCloseL(f) + assert b"very_secret" in data + + with ogr.Open(filename, update=1) as ds: + + with ds.ExecuteSQL("PRAGMA secure_delete") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 1 + + lyr = ds.GetLayer(0) + lyr.DeleteFeature(1) + + f = gdal.VSIFOpenL(filename, "rb") + data = gdal.VSIFReadL(1, 100000, f) + gdal.VSIFCloseL(f) + assert b"very_secret" not in data + + with gdaltest.config_option("OGR_SQLITE_PRAGMA", "secure_delete=0"): + with ogr.Open(filename, update=1) as ds: + with ds.ExecuteSQL("PRAGMA secure_delete") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == 0 + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. + + +@pytest.mark.parametrize( + "src_filename", + [ + # Generated with: ogr2ogr autotest/ogr/data/gpkg/poly_golden.gpkg autotest/ogr/data/poly.shp --config OGR_CURRENT_DATE="2000-01-01T:00:00:00.000Z" -nomd + "data/gpkg/poly_golden.gpkg", + ], +) +def test_ogr_gpkg_write_check_golden_file(tmp_path, src_filename): + + out_filename = str(tmp_path / "test.gpkg") + with gdal.config_option("OGR_CURRENT_DATE", "2000-01-01T:00:00:00.000Z"): + gdal.VectorTranslate(out_filename, src_filename) + + # Compare first sqlite3 dump if sqlite3 binary available + import subprocess + + try: + golden_dump = subprocess.check_output( + ["sqlite3", src_filename, ".dump"] + ).decode("utf-8") + got_dump = subprocess.check_output(["sqlite3", out_filename, ".dump"]).decode( + "utf-8" + ) + assert got_dump == golden_dump + # print("Identical sqlite3 dump") + except Exception: + pass + + if get_sqlite_version() >= (3, 46, 0): + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size + golden_data = bytearray(open(src_filename, "rb").read()) + got_data = bytearray(open(out_filename, "rb").read()) + # Zero out the SQLite version number at bytes 96-99. Cf https://www.sqlite.org/fileformat.html + golden_data[96] = golden_data[97] = golden_data[98] = golden_data[99] = 0 + got_data[96] = got_data[97] = got_data[98] = got_data[99] = 0 + assert got_data == golden_data diff --git a/autotest/ogr/ogr_gpsbabel.py b/autotest/ogr/ogr_gpsbabel.py index e1ddb7dceb14..4b5ce9f5bf57 100755 --- a/autotest/ogr/ogr_gpsbabel.py +++ b/autotest/ogr/ogr_gpsbabel.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_gpx.py b/autotest/ogr/ogr_gpx.py index 0d6d156fc99c..457f262c80e2 100755 --- a/autotest/ogr/ogr_gpx.py +++ b/autotest/ogr/ogr_gpx.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2007-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ogrtest diff --git a/autotest/ogr/ogr_gtfs.py b/autotest/ogr/ogr_gtfs.py index e8defefbed09..17856c0875ea 100755 --- a/autotest/ogr/ogr_gtfs.py +++ b/autotest/ogr/ogr_gtfs.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/ogr/ogr_hana.py b/autotest/ogr/ogr_hana.py index 479d6a85fdf4..16b4de256a25 100644 --- a/autotest/ogr/ogr_hana.py +++ b/autotest/ogr/ogr_hana.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, SAP SE # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from os import environ diff --git a/autotest/ogr/ogr_idrisi.py b/autotest/ogr/ogr_idrisi.py index bf8789cb5d48..4e65ad3cf60d 100755 --- a/autotest/ogr/ogr_idrisi.py +++ b/autotest/ogr/ogr_idrisi.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import ogrtest diff --git a/autotest/ogr/ogr_index_test.py b/autotest/ogr/ogr_index_test.py index 0044b44ccbe0..6b8fa6f5b10b 100755 --- a/autotest/ogr/ogr_index_test.py +++ b/autotest/ogr/ogr_index_test.py @@ -34,6 +34,8 @@ from osgeo import ogr +pytestmark = pytest.mark.require_driver("MapInfo File") + ############################################################################### diff --git a/autotest/ogr/ogr_jml.py b/autotest/ogr/ogr_jml.py index 021777c0163c..13da36faf116 100755 --- a/autotest/ogr/ogr_jml.py +++ b/autotest/ogr/ogr_jml.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_jsonfg.py b/autotest/ogr/ogr_jsonfg.py index a94636f7af96..4c23584e2eea 100755 --- a/autotest/ogr/ogr_jsonfg.py +++ b/autotest/ogr/ogr_jsonfg.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -950,7 +934,7 @@ def test_jsonfg_write_several_layers(): [["GEOMETRYCOLLECTION (POINT (1 2))"], ogr.wkbGeometryCollection], [["GEOMETRYCOLLECTION Z (POINT Z (1 2 3))"], ogr.wkbGeometryCollection25D], [["POINT (1 2)", "LINESTRING (1 2,3 4)"], ogr.wkbUnknown], - [["POLYHEDRALSURFACE EMPTY"], ogr.wkbPolyhedralSurface], + [["POLYHEDRALSURFACE Z EMPTY"], ogr.wkbPolyhedralSurfaceZ], [ [ "POLYHEDRALSURFACE Z (((0 0 0,0 1 0,1 1 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((0 0 0,0 1 0,0 0 1,0 0 0)),((0 1 0,1 0 0,0 0 1,0 1 0)))" diff --git a/autotest/ogr/ogr_kml.py b/autotest/ogr/ogr_kml.py index b90168dd04d5..957d93cb35f7 100755 --- a/autotest/ogr/ogr_kml.py +++ b/autotest/ogr/ogr_kml.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Matuesz Loskot # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -593,7 +577,7 @@ def test_ogr_kml_write_schema(tmp_vsimem): lyr - + strfield_val 1 @@ -664,7 +648,7 @@ def test_ogr_kml_two_layers(tmp_vsimem): empty lyr - + bar diff --git a/autotest/ogr/ogr_layer_algebra.py b/autotest/ogr/ogr_layer_algebra.py index cb43912ef18e..4e319ca04f55 100755 --- a/autotest/ogr/ogr_layer_algebra.py +++ b/autotest/ogr/ogr_layer_algebra.py @@ -10,23 +10,7 @@ # Copyright (c) 2012, Ari Jolma # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_libkml.py b/autotest/ogr/ogr_libkml.py index 777058abd284..52ece2b7786f 100755 --- a/autotest/ogr/ogr_libkml.py +++ b/autotest/ogr/ogr_libkml.py @@ -10,26 +10,9 @@ ############################################################################### # Copyright (c) 2010-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### - import gdaltest import ogrtest import pytest @@ -289,7 +272,8 @@ def ogr_libkml_write(filename): lyr = ds.CreateLayer("test_wgs72", srs=srs) assert lyr.TestCapability(ogr.OLCSequentialWrite) == 1 - assert lyr.TestCapability(ogr.OLCRandomWrite) == 0 + assert lyr.TestCapability(ogr.OLCRandomWrite) == 1 + assert lyr.TestCapability(ogr.OLCDeleteFeature) == 1 dst_feat = ogr.Feature(lyr.GetLayerDefn()) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt("POINT (2 49)")) @@ -530,6 +514,32 @@ def test_ogr_libkml_test_ogrsf(): ) +############################################################################### +# Run test_ogrsf + + +def test_ogr_libkml_test_ogrsf_write(tmp_path): + + test_filename = str(tmp_path / "test.kml") + gdal.VectorTranslate( + test_filename, "data/poly.shp", options="-s_srs EPSG:32631 -t_srs EPSG:4326" + ) + + import test_cli_utilities + + if test_cli_utilities.get_test_ogrsf_path() is None: + pytest.skip() + + ret = gdaltest.runexternal( + test_cli_utilities.get_test_ogrsf_path() + + f" --config OGR_SKIP KML {test_filename}" + ) + + assert "using driver `LIBKML'" in ret + assert "INFO" in ret + assert "ERROR" not in ret + + ############################################################################### # Test reading KML with only Placemark @@ -2253,3 +2263,82 @@ def test_ogr_libkml_write_geometries(input_wkt, expected_wkt, tmp_vsimem): assert f.GetGeometryRef().ExportToIsoWkt() == expected_wkt else: assert f is None + + +############################################################################### +# Test update of existing file + + +@pytest.mark.parametrize("custom_id", [False, True]) +def test_ogr_libkml_update_delete_existing_kml(tmp_vsimem, custom_id): + + filename = str(tmp_vsimem / "test.kml") + with ogr.GetDriverByName("LIBKML").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test") + assert lyr.TestCapability(ogr.OLCRandomWrite) == 1 + assert lyr.TestCapability(ogr.OLCDeleteFeature) == 1 + lyr.CreateField(ogr.FieldDefn("id")) + lyr.CreateField(ogr.FieldDefn("name")) + f = ogr.Feature(lyr.GetLayerDefn()) + if custom_id: + f["id"] = "feat1" + f["name"] = "name1" + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT (1 2)")) + lyr.CreateFeature(f) + assert lyr.TestCapability(ogr.OLCRandomWrite) == 1 + assert lyr.TestCapability(ogr.OLCDeleteFeature) == 1 + f = ogr.Feature(lyr.GetLayerDefn()) + if custom_id: + f["id"] = "feat2" + f["name"] = "name2" + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT (3 4)")) + lyr.CreateFeature(f) + + with gdal.OpenEx(filename, gdal.OF_VECTOR | gdal.OF_UPDATE) as ds: + lyr = ds.GetLayer(0) + assert lyr.TestCapability(ogr.OLCRandomWrite) == 1 + assert lyr.TestCapability(ogr.OLCDeleteFeature) == 1 + with pytest.raises(Exception, match="Non existing feature"): + lyr.DeleteFeature(0) + + with gdal.OpenEx(filename, gdal.OF_VECTOR | gdal.OF_UPDATE) as ds: + lyr = ds.GetLayer(0) + with pytest.raises(Exception, match="Non existing feature"): + lyr.DeleteFeature(3) + + with gdal.OpenEx(filename, gdal.OF_VECTOR | gdal.OF_UPDATE) as ds: + lyr = ds.GetLayer(0) + lyr.DeleteFeature(1) + assert lyr.GetFeatureCount() == 1 + lyr.ResetReading() + f = lyr.GetNextFeature() + assert f.GetFID() == 2 + if custom_id: + assert f["id"] == "feat2" + assert f["name"] == "name2" + f["name"] = "name2_updated" + lyr.SetFeature(f) + + with gdal.OpenEx(filename, gdal.OF_VECTOR | gdal.OF_UPDATE) as ds: + lyr = ds.GetLayer(0) + f = lyr.GetNextFeature() + if custom_id: + # FIDs are renumbered after feature update/deletion´if using + # custom KML ids + assert f.GetFID() == 1 + assert f["id"] == "feat2" + else: + assert f.GetFID() == 2 + assert f["name"] == "name2_updated" + + +############################################################################### +# Test that we don't report edit capabilities for a KML file without Placemark.id + + +def ogr_libkml_non_editable(): + + with gdal.OpenEx("data/kml/placemark.kml", gdal.OF_VECTOR | gdal.OF_UPDATE) as ds: + lyr = ds.GetLayer(0) + assert lyr.TestCapability(ogr.OLCRandomWrite) == 0 + assert lyr.TestCapability(ogr.OLCDeleteFeature) == 0 diff --git a/autotest/ogr/ogr_lvbag.py b/autotest/ogr/ogr_lvbag.py index 24154c580b6d..c72cfb621e8b 100644 --- a/autotest/ogr/ogr_lvbag.py +++ b/autotest/ogr/ogr_lvbag.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -603,3 +587,14 @@ def test_ogr_lvbag_test_ogrsf_num(): ) assert "INFO" in ret and "ERROR" not in ret + + +############################################################################### +# Test force opening + + +def test_ogr_lvbag_force_opening(): + + # Would be opened by GML driver if not forced + ds = gdal.OpenEx("data/gml/empty.gml", allowed_drivers=["LVBAG"]) + assert ds.GetDriver().GetDescription() == "LVBAG" diff --git a/autotest/ogr/ogr_mapml.py b/autotest/ogr/ogr_mapml.py index 71d75e6ef8e6..50038cf2ab6b 100755 --- a/autotest/ogr/ogr_mapml.py +++ b/autotest/ogr/ogr_mapml.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/ogr/ogr_mem.py b/autotest/ogr/ogr_mem.py index 0002d2c7487d..e763eb031d7c 100755 --- a/autotest/ogr/ogr_mem.py +++ b/autotest/ogr/ogr_mem.py @@ -10,23 +10,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -2888,9 +2872,12 @@ def test_ogr_mem_arrow_json(): lyr.CreateField(field_def) stream = lyr.GetArrowStreamAsPyArrow() - md = stream.schema["field_json"].metadata - assert b"ARROW:extension:name" in md - assert md[b"ARROW:extension:name"] == b"arrow.json" + field_schema = stream.schema["field_json"] + # Since pyarrow 18, the field type is extension + if str(field_schema.type) != "extension": + md = field_schema.metadata + assert b"ARROW:extension:name" in md + assert md[b"ARROW:extension:name"] == b"arrow.json" ############################################################################### diff --git a/autotest/ogr/ogr_miramon_vector.py b/autotest/ogr/ogr_miramon_vector.py index 410ea84f7ce9..2f69a8158c26 100644 --- a/autotest/ogr/ogr_miramon_vector.py +++ b/autotest/ogr/ogr_miramon_vector.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### # import os @@ -1444,3 +1428,47 @@ def test_ogr_miramon_create_field_after_feature(tmp_path): match="Cannot create fields to a layer with already existing features in it", ): create_common_attributes(lyr) + + +############################################################################### +# test reading mutirecord JSON file. At some point this test failed +# it's here to check that it's not failing (due to memory problems) + + +def test_ogr_miramon_json_import_not_failing(tmp_vsimem): + + out_filename = str(tmp_vsimem / "out/json_layer_to_mm.pol") + gdal.VectorTranslate( + out_filename, + "data/miramon_inputs/LT05_L2SP_038037_20120505_20200820_02_T1_ST_stac_minimal.json", + format="MiraMonVector", + ) + + ds = gdal.OpenEx(out_filename, gdal.OF_VECTOR) + + lyr = ds.GetLayer(0) + assert lyr is not None, "Failed to get layer" + + assert lyr.GetFeatureCount() == 1 + assert lyr.GetGeomType() == ogr.wkbPolygon + + f = lyr.GetNextFeature() + assert f is not None, "Failed to get feature" + assert f.GetFID() == 0 + + assert f.GetField("id") == [ + "LT05_L2SP_038037_20120505_20200820_02_T1_ST", + "", + "", + "", + "", + "", + ] + assert f.GetFieldAsString("datetime") == "(6:2012/05/05 17:54:06.781+00,,,,,)" + assert f.GetField("eo:cloud_cover") == [3.0] + assert f.GetField("proj:epsg") == [32611] + assert f.GetField("proj:shape") == [6951, 7851] + assert f.GetField("proj:transform") == [30.0, 0.0, 649485.0, 0.0, -30.0, 3780015.0] + + f = None + ds = None diff --git a/autotest/ogr/ogr_mitab.py b/autotest/ogr/ogr_mitab.py index 18d5daf96bc1..c692563b6809 100755 --- a/autotest/ogr/ogr_mitab.py +++ b/autotest/ogr/ogr_mitab.py @@ -2648,6 +2648,7 @@ def _test_srs(workdir, srs, input_srs=None, ext="tab"): assert srs if isinstance(srs, str): tmp = osr.SpatialReference() + tmp.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) tmp.SetFromUserInput(srs) srs = tmp if input_srs and isinstance(input_srs, str): @@ -2766,6 +2767,17 @@ def test_ogr_mitab_write_etrs89_from_custom_wkt_no_geogcs_code(tmp_vsimem): _test_srs(tmp_vsimem, srs, "EPSG:25832") +############################################################################### + + +def test_ogr_mitab_write_estonia_1977(tmp_vsimem): + + srs = osr.SpatialReference() + srs.ImportFromEPSG(3301) + srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) + _test_srs(tmp_vsimem, srs, "EPSG:3301") + + ############################################################################### # Test writing point with LABEL style string diff --git a/autotest/ogr/ogr_mongodbv3.py b/autotest/ogr/ogr_mongodbv3.py index 6b41e723e2d9..0c932ce0601f 100755 --- a/autotest/ogr/ogr_mongodbv3.py +++ b/autotest/ogr/ogr_mongodbv3.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015-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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_mssqlspatial.py b/autotest/ogr/ogr_mssqlspatial.py index 949ec06299ab..914c6f8e2093 100755 --- a/autotest/ogr/ogr_mssqlspatial.py +++ b/autotest/ogr/ogr_mssqlspatial.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_mvt.py b/autotest/ogr/ogr_mvt.py index 25b006385c7e..92ec8d2c9666 100755 --- a/autotest/ogr/ogr_mvt.py +++ b/autotest/ogr/ogr_mvt.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_nas.py b/autotest/ogr/ogr_nas.py index c548635f9706..07fc94749fd3 100755 --- a/autotest/ogr/ogr_nas.py +++ b/autotest/ogr/ogr_nas.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -304,3 +288,17 @@ def test_ogr_nas_force_opening(tmp_vsimem): with gdal.quiet_errors(): ds = gdal.OpenEx(filename, allowed_drivers=["NAS"]) assert ds.GetDriver().GetDescription() == "NAS" + + +############################################################################### +# Test we don't spend too much time parsing documents featuring the billion +# laugh attack + + +def test_ogr_nas_billion_laugh(): + + with gdal.config_option("NAS_GFS_TEMPLATE", ""): + with gdal.quiet_errors(), pytest.raises( + Exception, match="File probably corrupted" + ): + ogr.Open("data/nas/billionlaugh.xml") diff --git a/autotest/ogr/ogr_ngw.py b/autotest/ogr/ogr_ngw.py index 96874e0cd03f..eaced10c232c 100755 --- a/autotest/ogr/ogr_ngw.py +++ b/autotest/ogr/ogr_ngw.py @@ -10,23 +10,7 @@ # # Copyright (c) 2018-2021, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ################################################################################ import os diff --git a/autotest/ogr/ogr_ntf.py b/autotest/ogr/ogr_ntf.py index 6e0a7059042b..fdc1c5589915 100755 --- a/autotest/ogr/ogr_ntf.py +++ b/autotest/ogr/ogr_ntf.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### # The following tests will download sample data from diff --git a/autotest/ogr/ogr_oapif.py b/autotest/ogr/ogr_oapif.py index 53156723229e..6f62b21c13a4 100755 --- a/autotest/ogr/ogr_oapif.py +++ b/autotest/ogr/ogr_oapif.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2018, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -2199,3 +2183,82 @@ def test_ogr_oapif_initial_request_page_size(): ) with webserver.install_http_handler(handler): assert lyr.GetLayerDefn().GetFieldCount() == 1 + + +def test_ogr_oapif_datetime_open_option(): + """Test DATETIME open option""" + + handler = webserver.SequentialHandler() + handler.add( + "GET", + "/oapif/collections", + 200, + {"Content-Type": "application/json"}, + '{ "collections" : [ { "name": "foo" }] }', + ) + with webserver.install_http_handler(handler): + ds = gdal.OpenEx( + "http://localhost:%d/oapif" % gdaltest.webserver_port, + gdal.OF_VECTOR, + open_options=["DATETIME=2011-01-03T12:31:00Z"], + allowed_drivers=["OAPIF"], + ) + lyr = ds.GetLayer(0) + + handler = webserver.SequentialHandler() + _add_dummy_root_and_api_pages(handler) + handler.add( + "GET", + "/oapif/collections/foo/items?limit=20", + 200, + {"Content-Type": "application/geo+json"}, + """{ "type": "FeatureCollection", "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + } + } + ] }""", + ) + handler.add( + "GET", + "/oapif/collections/foo/items?limit=1000&datetime=2011-01-03T12:31:00Z", + 200, + {"Content-Type": "application/geo+json"}, + """{ "type": "FeatureCollection", "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + } + }, + { + "type": "Feature", + "properties": { + "bar": "baz" + } + } + ] }""", + ) + with webserver.install_http_handler(handler): + assert lyr.GetFeatureCount() == 2 + + handler = webserver.SequentialHandler() + handler.add( + "GET", + "/oapif/collections/foo/items?limit=1000&datetime=2011-01-03T12:31:00Z", + 200, + {"Content-Type": "application/geo+json"}, + """{ "type": "FeatureCollection", "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + } + } + ] }""", + ) + with webserver.install_http_handler(handler): + f = lyr.GetNextFeature() + assert f["foo"] == "bar" diff --git a/autotest/ogr/ogr_oci.py b/autotest/ogr/ogr_oci.py index 7952d947633a..02e3683cbea4 100755 --- a/autotest/ogr/ogr_oci.py +++ b/autotest/ogr/ogr_oci.py @@ -54,7 +54,10 @@ def setup_tests(): gdaltest.oci_ds.ExecuteSQL("DELLAYER:xpoly") gdaltest.oci_ds.ExecuteSQL("DELLAYER:testsrs") gdaltest.oci_ds.ExecuteSQL("DELLAYER:testsrs2") - gdaltest.oci_ds.ExecuteSQL("drop table geom_test") + try: + gdaltest.oci_ds.ExecuteSQL("drop table geom_test") + except Exception: + pass gdaltest.oci_ds.ExecuteSQL("DELLAYER:test_POINT") gdaltest.oci_ds.ExecuteSQL("DELLAYER:test_POINT3") gdaltest.oci_ds.ExecuteSQL("DELLAYER:test_LINESTRING") @@ -730,16 +733,21 @@ def test_ogr_oci_19(): feat.SetField("MYDATE", "2015/02/03") feat.SetField("MYDATETIME", "2015/02/03 11:33:44") lyr.CreateFeature(feat) + feat = ogr.Feature(lyr.GetLayerDefn()) + feat.SetField("MYDATETIME", "2015/02/03 11:33:44.12345") + lyr.CreateFeature(feat) lyr.SyncToDisk() - sql_lyr = gdaltest.oci_ds.ExecuteSQL("SELECT MYDATE, MYDATETIME FROM testdate") - assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetType() == ogr.OFTDate - assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetType() == ogr.OFTDateTime - f = sql_lyr.GetNextFeature() - if f.GetField(0) != "2015/02/03" or f.GetField(1) != "2015/02/03 11:33:44": - f.DumpReadable() - pytest.fail() - gdaltest.oci_ds.ReleaseResultSet(sql_lyr) + with gdaltest.oci_ds.ExecuteSQL( + "SELECT MYDATE, MYDATETIME FROM testdate" + ) as sql_lyr: + assert sql_lyr.GetLayerDefn().GetFieldDefn(0).GetType() == ogr.OFTDate + assert sql_lyr.GetLayerDefn().GetFieldDefn(1).GetType() == ogr.OFTDateTime + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == "2015/02/03" + assert f.GetField(1) == "2015/02/03 11:33:44" + f = sql_lyr.GetNextFeature() + assert f.GetField(1) == "2015/02/03 11:33:44.123" ############################################################################### diff --git a/autotest/ogr/ogr_odbc.py b/autotest/ogr/ogr_odbc.py index bf3f91e5301f..ebd0745ce184 100755 --- a/autotest/ogr/ogr_odbc.py +++ b/autotest/ogr/ogr_odbc.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_ods.py b/autotest/ogr/ogr_ods.py index 10c8c66e6e65..491665b09783 100755 --- a/autotest/ogr/ogr_ods.py +++ b/autotest/ogr/ogr_ods.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_ogdi.py b/autotest/ogr/ogr_ogdi.py index 8d200305ab9c..3d9accf1d891 100755 --- a/autotest/ogr/ogr_ogdi.py +++ b/autotest/ogr/ogr_ogdi.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_ogrtest.py b/autotest/ogr/ogr_ogrtest.py index 3389bf833877..f30057122f61 100644 --- a/autotest/ogr/ogr_ogrtest.py +++ b/autotest/ogr/ogr_ogrtest.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, ISciences LLC # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import ogrtest diff --git a/autotest/ogr/ogr_openfilegdb.py b/autotest/ogr/ogr_openfilegdb.py index 2d1724f7d1e8..34abc6d8c257 100755 --- a/autotest/ogr/ogr_openfilegdb.py +++ b/autotest/ogr/ogr_openfilegdb.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_openfilegdb_write.py b/autotest/ogr/ogr_openfilegdb_write.py index 4e9c3f00535a..d2b0486267a4 100755 --- a/autotest/ogr/ogr_openfilegdb_write.py +++ b/autotest/ogr/ogr_openfilegdb_write.py @@ -10,25 +10,10 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import os import struct import sys @@ -4281,7 +4266,7 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem): lyr = ds.GetLayerByName("date_types") lyr_defn = lyr.GetLayerDefn() - fld_defn = lyr_defn.GetFieldDefn(lyr_defn.GetFieldIndex("date_")) + fld_defn = lyr_defn.GetFieldDefn(lyr_defn.GetFieldIndex("date")) assert fld_defn.GetType() == ogr.OFTDateTime assert fld_defn.GetDefault() == "'2023/02/01 04:05:06'" @@ -4298,13 +4283,13 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem): assert fld_defn.GetDefault() == "'2023/02/01 04:05:06.000+06:00'" f = lyr.GetNextFeature() - assert f["date_"] == "2023/11/29 13:14:15+00" + assert f["date"] == "2023/11/29 13:14:15+00" assert f["date_only"] == "2023/11/29" assert f["time_only"] == "13:14:15" assert f["timestamp_offset"] == "2023/11/29 13:14:15-05" f = lyr.GetNextFeature() - assert f["date_"] == "2023/12/31 00:01:01+00" + assert f["date"] == "2023/12/31 00:01:01+00" assert f["date_only"] == "2023/12/31" assert f["time_only"] == "00:01:01" assert f["timestamp_offset"] == "2023/12/31 00:01:01+10" @@ -4313,13 +4298,13 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem): lyr_defn = lyr.GetLayerDefn() f = lyr.GetNextFeature() - assert f["date_"] == "2023/11/29 13:14:15.678+00" + assert f["date"] == "2023/11/29 13:14:15.678+00" assert f["date_only"] == "2023/11/29" assert f["time_only"] == "13:14:15" assert f["timestamp_offset"] == "2023/11/29 13:14:15-05" f = lyr.GetNextFeature() - assert f["date_"] == "2023/12/31 00:01:01.001+00" + assert f["date"] == "2023/12/31 00:01:01.001+00" assert f["date_only"] == "2023/12/31" assert f["time_only"] == "00:01:01" assert f["timestamp_offset"] == "2023/12/31 00:01:01+10" @@ -4587,3 +4572,32 @@ def test_ogr_openfilegdb_write_OGRUnsetMarker(tmp_vsimem): lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert f["i32"] == -21121 + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. + + +@pytest.mark.parametrize( + "src_directory", + [ + # Generated with: + # ogr2ogr autotest/ogr/data/openfilegdb/polygon_golden.gdb '{"type":"Feature","properties":{"foo":"bar"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[0,1],[1,0],[0,0]]]}}' --config OPENFILEGDB_CREATOR GDAL --config OPENFILEGDB_REPRODUCIBLE_UUID YES -f openfilegdb + "data/openfilegdb/polygon_golden.gdb", + ], +) +def test_ogr_openfilegdb_write_check_golden_file(tmp_path, src_directory): + + out_directory = str(tmp_path / "test.gdb") + with gdaltest.config_options( + {"OPENFILEGDB_CREATOR": "GDAL", "OPENFILEGDB_REPRODUCIBLE_UUID": "YES"} + ): + gdal.VectorTranslate(out_directory, src_directory, format="OpenFileGDB") + for filename in os.listdir(src_directory): + src_filename = os.path.join(src_directory, filename) + out_filename = os.path.join(out_directory, filename) + + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size, filename + assert ( + open(src_filename, "rb").read() == open(out_filename, "rb").read() + ), filename diff --git a/autotest/ogr/ogr_osm.py b/autotest/ogr/ogr_osm.py index 09666b00edbd..70f664fc5b28 100755 --- a/autotest/ogr/ogr_osm.py +++ b/autotest/ogr/ogr_osm.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -937,6 +921,13 @@ def test_ogr_osm_tags_json_special_characters(): def test_ogr_osmconf_ini(): + if "EMBED_RESOURCE_FILES=YES" in gdal.VersionInfo( + "BUILD_INFO" + ) or "USE_ONLY_EMBEDDED_RESOURCE_FILES=YES" in gdal.VersionInfo("BUILD_INFO"): + pytest.skip( + "Test cannot work with EMBED_RESOURCE_FILES=YES/USE_ONLY_EMBEDDED_RESOURCE_FILES=YES" + ) + import configparser with ogr.Open("data/osm/test_json.pbf") as ds: diff --git a/autotest/ogr/ogr_parquet.py b/autotest/ogr/ogr_parquet.py index 2563010535ac..912ca56c34e3 100755 --- a/autotest/ogr/ogr_parquet.py +++ b/autotest/ogr/ogr_parquet.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -3870,6 +3854,8 @@ def check(lyr): lyr = ds.GetLayer(0) lyr.SetIgnoredFields(["foo"]) check(lyr) + lyr.SetSpatialFilter(geom) + assert lyr.GetFeatureCount() == (3 if geom.GetGeometryCount() > 1 else 2) ds = ogr.Open(filename_to_open) lyr = ds.GetLayer(0) @@ -4122,6 +4108,63 @@ def test_ogr_parquet_vsi_arrow_file_system(): if version < 16: pytest.skip("requires Arrow >= 16.0.0") - ds = ogr.Open("PARQUET:vsi://data/parquet/test.parquet") + ds = ogr.Open("PARQUET:gdalvsi://data/parquet/test.parquet") lyr = ds.GetLayer(0) assert lyr.GetFeatureCount() > 0 + + +############################################################################### + + +@gdaltest.enable_exceptions() +@pytest.mark.require_driver("ARROW") +@pytest.mark.parametrize( + "src_filename,expected_error_msg", + [ + ("data/arrow/stringview.feather", "StringView not supported"), + ("data/arrow/binaryview.feather", "BinaryView not supported"), + ], +) +def test_ogr_parquet_IsArrowSchemaSupported_arrow_15_types( + src_filename, expected_error_msg, tmp_vsimem +): + + version = int( + ogr.GetDriverByName("ARROW").GetMetadataItem("ARROW_VERSION").split(".")[0] + ) + if version < 15: + pytest.skip("requires Arrow >= 15.0.0") + + src_ds = ogr.Open(src_filename) + src_lyr = src_ds.GetLayer(0) + + outfilename = str(tmp_vsimem / "test.parquet") + with ogr.GetDriverByName("Parquet").CreateDataSource(outfilename) as dst_ds: + dst_lyr = dst_ds.CreateLayer( + "test", srs=src_lyr.GetSpatialRef(), geom_type=ogr.wkbPoint, options=[] + ) + + stream = src_lyr.GetArrowStream() + schema = stream.GetSchema() + + success, error_msg = dst_lyr.IsArrowSchemaSupported(schema) + assert not success + assert error_msg == expected_error_msg + + +############################################################################### + + +def test_ogr_parquet_ogr2ogr_reprojection(tmp_vsimem): + + outfilename = str(tmp_vsimem / "test.parquet") + gdal.VectorTranslate( + outfilename, + "data/parquet/poly.parquet", + srcSRS="EPSG:32632", + dstSRS="EPSG:4326", + ) + with ogr.Open(outfilename) as ds: + assert ds.GetLayer(0).GetExtent() == pytest.approx( + (8.73380363499761, 8.774681944824946, 43.01833481785084, 43.04292637071279) + ) diff --git a/autotest/ogr/ogr_pcidsk.py b/autotest/ogr/ogr_pcidsk.py index c229db2fda52..2f225ca5d02d 100755 --- a/autotest/ogr/ogr_pcidsk.py +++ b/autotest/ogr/ogr_pcidsk.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_pdf.py b/autotest/ogr/ogr_pdf.py index 442ffcde50dc..9be31d4db7bd 100755 --- a/autotest/ogr/ogr_pdf.py +++ b/autotest/ogr/ogr_pdf.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -54,7 +38,7 @@ def has_read_support(): return True -@pytest.fixture(params=("DEFAULT", "PODOFO")) +@pytest.fixture(params=("DEFAULT", "PDFIUM", "POPPLER", "PODOFO")) def pdf_lib(request): lib_name = request.param @@ -454,8 +438,10 @@ def test_ogr_pdf_arcgis_12_9(): force_download="CI" in os.environ, ) - ds = ogr.Open("tmp/cache/9130-3N+PARRAMATTA+RIVER.pdf") - assert ds.GetLayerCount() == 58 + # OGR_ORGANIZE_POLYGONS=SKIP to make the test as fast as possible + with gdaltest.config_option("OGR_ORGANIZE_POLYGONS", "SKIP"): + ds = ogr.Open("tmp/cache/9130-3N+PARRAMATTA+RIVER.pdf") + assert ds.GetLayerCount() == 66 lyr = ds.GetLayer("Background") background_extent = lyr.GetExtent() assert background_extent == pytest.approx( @@ -468,3 +454,23 @@ def test_ogr_pdf_arcgis_12_9(): (314770.38136460556, 338159.3346125973, 6249907.04700745, 6264139.920707164), rel=1e-5, ) + + +############################################################################### +# Test bugfix for https://github.com/OSGeo/gdal/issues/11034 + + +@pytest.mark.skipif(not has_read_support(), reason="PDF driver lacks read support") +def test_ogr_pdf_recursive_resources_and_oc_name_and_empty_ocg_name(pdf_lib): + + with ogr.Open( + "data/pdf/recursive_resources_and_oc_name_and_empty_ocg_name.pdf" + ) as ds: + assert ds.GetLayerCount() == 1 + lyr = ds.GetLayer("unnamed") + assert lyr.GetFeatureCount() == 4 + feat = lyr.GetNextFeature() + expected_wkt = """LINESTRING (210719.044079199 5340565.58196092,210703.077661677 5340510.89851925)""" + ogrtest.check_feature_geometry( + feat, ogr.CreateGeometryFromWkt(expected_wkt), max_error=1 + ) diff --git a/autotest/ogr/ogr_pds.py b/autotest/ogr/ogr_pds.py index 8bfe278f00a7..341886c301b9 100755 --- a/autotest/ogr/ogr_pds.py +++ b/autotest/ogr/ogr_pds.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_pds4.py b/autotest/ogr/ogr_pds4.py index d05d0e08c245..900ccf2db52c 100755 --- a/autotest/ogr/ogr_pds4.py +++ b/autotest/ogr/ogr_pds4.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2019, Hobu Inc # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import contextlib diff --git a/autotest/ogr/ogr_pg.py b/autotest/ogr/ogr_pg.py index 65e1ac68ffaa..4efceeff0d1e 100755 --- a/autotest/ogr/ogr_pg.py +++ b/autotest/ogr/ogr_pg.py @@ -4849,6 +4849,13 @@ def test_ogr_pg_84(pg_ds): def test_ogr_pg_metadata(pg_ds, run_number): pg_ds = reconnect(pg_ds, update=1) + + if run_number == 1: + pg_ds.ExecuteSQL( + "DROP EVENT TRIGGER IF EXISTS ogr_system_tables_event_trigger_for_metadata" + ) + pg_ds.ExecuteSQL("DROP SCHEMA ogr_system_tables CASCADE") + pg_ds.StartTransaction() lyr = pg_ds.CreateLayer( "test_ogr_pg_metadata", geom_type=ogr.wkbPoint, options=["OVERWRITE=YES"] @@ -4903,7 +4910,6 @@ def test_ogr_pg_metadata_restricted_user(pg_ds): pg_ds = reconnect(pg_ds, update=1) try: - pg_ds.ExecuteSQL("CREATE ROLE test_ogr_pg_metadata_restricted_user") with pg_ds.ExecuteSQL("SELECT current_schema()") as lyr: f = lyr.GetNextFeature() @@ -4923,6 +4929,7 @@ def test_ogr_pg_metadata_restricted_user(pg_ds): ) pg_ds = reconnect(pg_ds, update=1) + pg_ds.ExecuteSQL("DROP SCHEMA ogr_system_tables CASCADE") pg_ds.ExecuteSQL("SET ROLE test_ogr_pg_metadata_restricted_user") lyr = pg_ds.CreateLayer( @@ -4933,9 +4940,12 @@ def test_ogr_pg_metadata_restricted_user(pg_ds): with gdal.quiet_errors(): lyr.SetMetadata({"foo": "bar"}) - gdal.ErrorReset() - pg_ds = reconnect(pg_ds, update=1) - assert gdal.GetLastErrorMsg() == "" + gdal.ErrorReset() + pg_ds = reconnect(pg_ds, update=1) + assert ( + gdal.GetLastErrorMsg() + == "User lacks super user privilege to be able to create event trigger ogr_system_tables_event_trigger_for_metadata" + ) finally: pg_ds = reconnect(pg_ds, update=1) @@ -5910,6 +5920,27 @@ def test_ogr_pg_long_identifiers(pg_ds): assert lyr.CreateFeature(f) == ogr.OGRERR_NONE assert lyr.SyncToDisk() == ogr.OGRERR_NONE + long_name3 = "test_" + ("X" * (64 - len("test_"))) + assert len(long_name3) == 64 + short_name3 = "test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_b7ebb17c" + assert len(short_name3) == 63 + with gdal.quiet_errors(): + lyr = pg_ds.CreateLayer(long_name3) + assert lyr.GetName() == short_name3 + f = ogr.Feature(lyr.GetLayerDefn()) + assert lyr.CreateFeature(f) == ogr.OGRERR_NONE + assert lyr.SyncToDisk() == ogr.OGRERR_NONE + + long_name4 = "test_" + ("X" * (63 - len("test_"))) + assert len(long_name4) == 63 + short_name4 = "test_" + ("x" * (63 - len("test_"))) + with gdal.quiet_errors(): + lyr = pg_ds.CreateLayer(long_name4) + assert lyr.GetName() == short_name4 + f = ogr.Feature(lyr.GetLayerDefn()) + assert lyr.CreateFeature(f) == ogr.OGRERR_NONE + assert lyr.SyncToDisk() == ogr.OGRERR_NONE + pg_ds = reconnect(pg_ds, update=1) got_lyr = pg_ds.GetLayerByName(short_name) @@ -5920,6 +5951,14 @@ def test_ogr_pg_long_identifiers(pg_ds): assert got_lyr assert got_lyr.GetName() == short_name2 + got_lyr = pg_ds.GetLayerByName(short_name3) + assert got_lyr + assert got_lyr.GetName() == short_name3 + + got_lyr = pg_ds.GetLayerByName(short_name4) + assert got_lyr + assert got_lyr.GetName() == short_name4 + ############################################################################### # Test extent 3D @@ -6161,3 +6200,72 @@ def test_ogr_pg_ogr2ogr_with_multiple_dotted_table_name(pg_ds): finally: pg_ds.ExecuteSQL(f'DROP SCHEMA "{tmp_schema}" CASCADE') + + +############################################################################### +# Test scenario of https://lists.osgeo.org/pipermail/gdal-dev/2024-October/059608.html + + +@only_without_postgis +@gdaltest.enable_exceptions() +def test_ogr_pg_empty_search_path(pg_ds): + + with pg_ds.ExecuteSQL("SHOW search_path") as sql_lyr: + f = sql_lyr.GetNextFeature() + old_search_path = f.GetField(0) + old_search_path = old_search_path.replace( + "test_ogr_pg_empty_search_path_no_postgis, ", "" + ) + + with pg_ds.ExecuteSQL("SELECT CURRENT_USER") as lyr: + f = lyr.GetNextFeature() + current_user = f.GetField(0) + pg_ds.ExecuteSQL(f"ALTER ROLE {current_user} SET search_path = ''") + try: + ds = reconnect(pg_ds, update=1) + + with ds.ExecuteSQL("SHOW search_path") as sql_lyr: + f = sql_lyr.GetNextFeature() + new_search_path = f.GetField(0) + assert new_search_path == "test_ogr_pg_empty_search_path_no_postgis, public" + + finally: + ds.ExecuteSQL(f"ALTER ROLE {current_user} SET search_path = {old_search_path}") + + +############################################################################### +# Test appending to a layer where a field name was truncated to 63 characters. + + +@only_without_postgis +@gdaltest.enable_exceptions() +def test_ogr_pg_findfield(pg_ds): + + src_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + src_lyr = src_ds.CreateLayer("test_very_long_field_name") + src_lyr.CreateField( + ogr.FieldDefn( + "veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeryyyyyyyyyyyyyyyyyyyyyyloooooooooooooong" + ) + ) + f = ogr.Feature(src_lyr.GetLayerDefn()) + f.SetField(0, "foo") + src_lyr.CreateFeature(f) + + with gdal.quiet_errors(): + gdal.VectorTranslate(pg_ds.GetDescription(), src_ds) + + with gdal.quiet_errors(): + gdal.VectorTranslate(pg_ds.GetDescription(), src_ds, accessMode="append") + + lyr = pg_ds.GetLayerByName("test_very_long_field_name") + assert [f.GetField(0) for f in lyr] == ["foo", None] + + with gdal.quiet_errors(): + gdal.VectorTranslate( + pg_ds.GetDescription(), + src_ds, + accessMode="append", + relaxedFieldNameMatch=True, + ) + assert [f.GetField(0) for f in lyr] == ["foo", None, "foo"] diff --git a/autotest/ogr/ogr_pgdump.py b/autotest/ogr/ogr_pgdump.py index 7be8981c89e2..1472b05f5aa3 100755 --- a/autotest/ogr/ogr_pgdump.py +++ b/autotest/ogr/ogr_pgdump.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/ogr/ogr_pgeo.py b/autotest/ogr/ogr_pgeo.py index 66f4a3f39aed..a1dfcfa7af60 100755 --- a/autotest/ogr/ogr_pgeo.py +++ b/autotest/ogr/ogr_pgeo.py @@ -10,26 +10,11 @@ ############################################################################### # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os +import shutil import sys import gdaltest @@ -977,3 +962,14 @@ def test_ogr_openfilegdb_read_relationships(): assert rel.GetForwardPathLabel() == "attachment" assert rel.GetBackwardPathLabel() == "object" assert rel.GetRelatedTableType() == "media" + + +def test_ogr_pgeo_non_ascii(tmp_path): + + non_ascii_filename = str(tmp_path / "éé.mdb") + shutil.copy("data/pgeo/sample.mdb", non_ascii_filename) + + pgeo_ds = ogr.Open(non_ascii_filename) + assert pgeo_ds is not None + + assert pgeo_ds.GetLayerCount() == 4 diff --git a/autotest/ogr/ogr_plscenes.py b/autotest/ogr/ogr_plscenes.py index 3b386021d50d..aae005636025 100755 --- a/autotest/ogr/ogr_plscenes.py +++ b/autotest/ogr/ogr_plscenes.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_pmtiles.py b/autotest/ogr/ogr_pmtiles.py index d554a41e1c79..242a85124d9d 100755 --- a/autotest/ogr/ogr_pmtiles.py +++ b/autotest/ogr/ogr_pmtiles.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2023, Planet Labs # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_pythondrivers.py b/autotest/ogr/ogr_pythondrivers.py index 3b2e4fee8fd8..8d173c2f3271 100644 --- a/autotest/ogr/ogr_pythondrivers.py +++ b/autotest/ogr/ogr_pythondrivers.py @@ -9,23 +9,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_rfc30.py b/autotest/ogr/ogr_rfc30.py index df5698e95f54..7efb6f955cb2 100755 --- a/autotest/ogr/ogr_rfc30.py +++ b/autotest/ogr/ogr_rfc30.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### from osgeo import ogr diff --git a/autotest/ogr/ogr_rfc35.py b/autotest/ogr/ogr_rfc35.py index 65b00dd71f25..2688e1199088 100755 --- a/autotest/ogr/ogr_rfc35.py +++ b/autotest/ogr/ogr_rfc35.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_rfc41.py b/autotest/ogr/ogr_rfc41.py index 9befbaa54667..9e8cccbd9c19 100755 --- a/autotest/ogr/ogr_rfc41.py +++ b/autotest/ogr/ogr_rfc41.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_s57.py b/autotest/ogr/ogr_s57.py index 5fc19302ad3a..40f461a3800e 100755 --- a/autotest/ogr/ogr_s57.py +++ b/autotest/ogr/ogr_s57.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_sdts.py b/autotest/ogr/ogr_sdts.py index cd1f4323a95d..97a18a0c6bf2 100755 --- a/autotest/ogr/ogr_sdts.py +++ b/autotest/ogr/ogr_sdts.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_selafin.py b/autotest/ogr/ogr_selafin.py index a56e27241594..15123f3551f7 100755 --- a/autotest/ogr/ogr_selafin.py +++ b/autotest/ogr/ogr_selafin.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2014, François Hissel # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math diff --git a/autotest/ogr/ogr_shape.py b/autotest/ogr/ogr_shape.py index 889d0c688abd..d777a11e41bc 100755 --- a/autotest/ogr/ogr_shape.py +++ b/autotest/ogr/ogr_shape.py @@ -6134,3 +6134,34 @@ def test_ogr_shape_read_date_empty_string(): lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert f["date"] is None + + +############################################################################### +# Verify that we can generate an output that is byte-identical to the expected golden file. + + +@pytest.mark.parametrize( + "src_directory", + [ + # Generated with: + # ogr2ogr autotest/ogr/data/shp/poly_golden autotest/ogr/data/poly.shp -lco DBF_DATE_LAST_UPDATE=2000-01-01 + "data/shp/poly_golden", + ], +) +def test_ogr_shape_write_check_golden_file(tmp_path, src_directory): + + out_directory = str(tmp_path / "test") + gdal.VectorTranslate( + out_directory, + src_directory, + format="ESRI Shapefile", + layerCreationOptions=["DBF_DATE_LAST_UPDATE=2000-01-01"], + ) + for filename in os.listdir(src_directory): + src_filename = os.path.join(src_directory, filename) + out_filename = os.path.join(out_directory, filename) + + assert os.stat(src_filename).st_size == os.stat(out_filename).st_size, filename + assert ( + open(src_filename, "rb").read() == open(out_filename, "rb").read() + ), filename diff --git a/autotest/ogr/ogr_shape_qix.py b/autotest/ogr/ogr_shape_qix.py index 7de68d941b03..6ed720fec125 100755 --- a/autotest/ogr/ogr_shape_qix.py +++ b/autotest/ogr/ogr_shape_qix.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import random diff --git a/autotest/ogr/ogr_shape_sbn.py b/autotest/ogr/ogr_shape_sbn.py index f528308b6e6e..152af2f39818 100755 --- a/autotest/ogr/ogr_shape_sbn.py +++ b/autotest/ogr/ogr_shape_sbn.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_sosi.py b/autotest/ogr/ogr_sosi.py index 3975da730b04..572059c1b753 100755 --- a/autotest/ogr/ogr_sosi.py +++ b/autotest/ogr/ogr_sosi.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil diff --git a/autotest/ogr/ogr_sql_rfc28.py b/autotest/ogr/ogr_sql_rfc28.py index 0fa8d763bf73..4405220bfb17 100755 --- a/autotest/ogr/ogr_sql_rfc28.py +++ b/autotest/ogr/ogr_sql_rfc28.py @@ -11,23 +11,7 @@ # Copyright (c) 2010, Frank Warmerdam # Copyright (c) 2010-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_sql_sqlite.py b/autotest/ogr/ogr_sql_sqlite.py index 5c66950c9f07..b6b1bafb2ead 100755 --- a/autotest/ogr/ogr_sql_sqlite.py +++ b/autotest/ogr/ogr_sql_sqlite.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_sql_test.py b/autotest/ogr/ogr_sql_test.py index e9c187219bed..fe517750e5d3 100755 --- a/autotest/ogr/ogr_sql_test.py +++ b/autotest/ogr/ogr_sql_test.py @@ -102,7 +102,9 @@ def get_lyr(): with pytest.raises(Exception): lyr.GetName() - assert get_lyr().GetFeatureCount() == 10 + # This leaks memory + if not gdaltest.is_travis_branch("sanitize"): + assert get_lyr().GetFeatureCount() == 10 # Check that we can actually remove the files (i.e. references on dataset have been dropped) os.unlink(tmp_path / "test_ogr_sql_execute_sql.shp") @@ -419,6 +421,7 @@ def test_ogr_sql_13(data_ds): # Verify selection of, and on ogr_style and ogr_geom_wkt. +@pytest.mark.require_driver("MapInfo File") def test_ogr_sql_14(): expect = [ @@ -452,6 +455,7 @@ def test_ogr_sql_15(data_ds): ############################################################################### +@pytest.mark.require_driver("MapInfo File") def test_ogr_sql_16(): expect = [2] @@ -465,6 +469,7 @@ def test_ogr_sql_16(): ############################################################################### # Test the RFC 21 CAST operator. # +@pytest.mark.require_driver("MapInfo File") def test_ogr_sql_17(): expect = ["1", "2"] @@ -1285,6 +1290,7 @@ def test_ogr_sql_hstore_get_value_valid(data_ds, sql, expected): # Test 64 bit GetFeatureCount() +@pytest.mark.require_driver("OGR_VRT") def test_ogr_sql_45(): ds = ogr.Open( @@ -1946,6 +1952,13 @@ def get_available_dialects(): ("(NOT intfield = 0) AND NOT (intfield IS NULL)", 1), ("NOT (intfield = 0 OR intfield IS NOT NULL)", 0), ("(NOT intfield = 0) AND NOT (intfield IS NOT NULL)", 0), + ("intfield <> 0 AND intfield <> 2", 1), + ("intfield IS NOT NULL AND intfield NOT IN (2)", 1), + ("NOT(intfield NOT IN (1) AND NULL NOT IN (1))", 1), + ("NOT(intfield IS NOT NULL AND intfield NOT IN (2))", 1), + ("NOT(NOT(intfield IS NOT NULL AND intfield NOT IN (2)))", 1), + ("NOT (intfield = 0 AND intfield = 0)", 1), + ("(intfield NOT IN (1) AND NULL NOT IN (1)) IS NULL", 1), # realfield ("1 + realfield >= 0", 1), ("realfield = 0", 0), diff --git a/autotest/ogr/ogr_sqlite.py b/autotest/ogr/ogr_sqlite.py index 762f66c868bc..0d5d22526c2c 100755 --- a/autotest/ogr/ogr_sqlite.py +++ b/autotest/ogr/ogr_sqlite.py @@ -11,23 +11,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -4149,6 +4133,123 @@ def test_ogr_sqlite_stddev(): assert f.GetField(1) == pytest.approx(0.5**0.5, rel=1e-15) +@pytest.mark.parametrize( + "input_values,expected_res", + [ + ([], None), + ([1], 1), + ([2.5, None, 1], 1.75), + ([3, 2.2, 1], 2.2), + ([1, "invalid"], None), + ], +) +def test_ogr_sqlite_median(input_values, expected_res): + """Test MEDIAN""" + + ds = ogr.Open(":memory:", update=1) + ds.ExecuteSQL("CREATE TABLE test(v)") + for v in input_values: + ds.ExecuteSQL( + "INSERT INTO test VALUES (%s)" + % ( + "NULL" + if v is None + else ("'" + v + "'") + if isinstance(v, str) + else str(v) + ) + ) + if expected_res is None and input_values: + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT MEDIAN(v) FROM test"): + pass + else: + with ds.ExecuteSQL("SELECT MEDIAN(v) FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == pytest.approx(expected_res) + with ds.ExecuteSQL("SELECT PERCENTILE(v, 50) FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == pytest.approx(expected_res) + with ds.ExecuteSQL("SELECT PERCENTILE_CONT(v, 0.5) FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == pytest.approx(expected_res) + + +def test_ogr_sqlite_percentile(): + """Test PERCENTILE""" + + ds = ogr.Open(":memory:", update=1) + ds.ExecuteSQL("CREATE TABLE test(v)") + ds.ExecuteSQL("INSERT INTO test VALUES (5),(6),(4),(7),(3),(8),(2),(9),(1),(10)") + + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE(v, 'invalid') FROM test"): + pass + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE(v, -0.1) FROM test"): + pass + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE(v, 100.1) FROM test"): + pass + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE(v, v) FROM test"): + pass + + +def test_ogr_sqlite_percentile_cont(): + """Test PERCENTILE_CONT""" + + ds = ogr.Open(":memory:", update=1) + ds.ExecuteSQL("CREATE TABLE test(v)") + ds.ExecuteSQL("INSERT INTO test VALUES (5),(6),(4),(7),(3),(8),(2),(9),(1),(10)") + + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE_CONT(v, 'invalid') FROM test"): + pass + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE_CONT(v, -0.1) FROM test"): + pass + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT PERCENTILE_CONT(v, 1.1) FROM test"): + pass + + +@pytest.mark.parametrize( + "input_values,expected_res", + [ + ([], None), + ([1, 2, None, 3, 2], 2), + (["foo", "bar", "baz", "bar"], "bar"), + ([1, "foo", 2, "foo", "bar"], "foo"), + ([1, "foo", 2, "foo", 1], "foo"), + ], +) +def test_ogr_sqlite_mode(input_values, expected_res): + """Test MODE""" + + ds = ogr.Open(":memory:", update=1) + ds.ExecuteSQL("CREATE TABLE test(v)") + for v in input_values: + ds.ExecuteSQL( + "INSERT INTO test VALUES (%s)" + % ( + "NULL" + if v is None + else ("'" + v + "'") + if isinstance(v, str) + else str(v) + ) + ) + if expected_res is None and input_values: + with pytest.raises(Exception), gdaltest.error_handler(): + with ds.ExecuteSQL("SELECT MODE(v) FROM test"): + pass + else: + with ds.ExecuteSQL("SELECT MODE(v) FROM test") as sql_lyr: + f = sql_lyr.GetNextFeature() + assert f.GetField(0) == expected_res + + def test_ogr_sqlite_run_deferred_actions_before_start_transaction(): ds = ogr.Open(":memory:", update=1) diff --git a/autotest/ogr/ogr_style.py b/autotest/ogr/ogr_style.py index 3457ee10e426..982df084a2be 100755 --- a/autotest/ogr/ogr_style.py +++ b/autotest/ogr/ogr_style.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_svg.py b/autotest/ogr/ogr_svg.py index 768d8fd23e32..7d564b3d28fa 100755 --- a/autotest/ogr/ogr_svg.py +++ b/autotest/ogr/ogr_svg.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_sxf.py b/autotest/ogr/ogr_sxf.py index 8cff70753320..b769f8f34199 100755 --- a/autotest/ogr/ogr_sxf.py +++ b/autotest/ogr/ogr_sxf.py @@ -71,11 +71,11 @@ def test_ogr_sxf_2(): # Open SXF datasource with custom RSC file. -def test_ogr_sxf_3(): +def test_ogr_sxf_3(tmp_path): lyr_names = ["SYSTEM", "Not_Classified"] - sxf_name = "tmp/test_ogr_sxf_3.sxf" - rsc_name = "tmp/test_ogr_sxf_3.rsc" + sxf_name = str(tmp_path / "test_ogr_sxf_3.sxf") + rsc_name = str(tmp_path / "test_ogr_sxf_3.rsc") fake_rsc = open(rsc_name, "w") fake_rsc.close() shutil.copy("data/sxf/100_test.sxf", sxf_name) diff --git a/autotest/ogr/ogr_tiger.py b/autotest/ogr/ogr_tiger.py index 84371e1433e2..636896ccf980 100755 --- a/autotest/ogr/ogr_tiger.py +++ b/autotest/ogr/ogr_tiger.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2011-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_tiledb.py b/autotest/ogr/ogr_tiledb.py index 23520b55d124..067f9e35906c 100644 --- a/autotest/ogr/ogr_tiledb.py +++ b/autotest/ogr/ogr_tiledb.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/ogr/ogr_topojson.py b/autotest/ogr/ogr_topojson.py index 1580ca7d7c9f..9dc502868aee 100755 --- a/autotest/ogr/ogr_topojson.py +++ b/autotest/ogr/ogr_topojson.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -35,6 +19,8 @@ from osgeo import gdal, ogr +pytestmark = pytest.mark.require_driver("TopoJSON") + ############################################################################### # Test TopoJSON diff --git a/autotest/ogr/ogr_vdv.py b/autotest/ogr/ogr_vdv.py index c358c29b77b8..aa0a277f2b96 100755 --- a/autotest/ogr/ogr_vdv.py +++ b/autotest/ogr/ogr_vdv.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_vfk.py b/autotest/ogr/ogr_vfk.py index acd3324308a9..73a2ffc24e63 100755 --- a/autotest/ogr/ogr_vfk.py +++ b/autotest/ogr/ogr_vfk.py @@ -11,23 +11,7 @@ # Copyright (c) 2009-2019 Martin Landa # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pathlib diff --git a/autotest/ogr/ogr_virtualogr.py b/autotest/ogr/ogr_virtualogr.py index 39a9b90df867..91a4fdebc03c 100755 --- a/autotest/ogr/ogr_virtualogr.py +++ b/autotest/ogr/ogr_virtualogr.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2012-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/ogr/ogr_vrt.py b/autotest/ogr/ogr_vrt.py index e5afc296eb04..43e8c612a548 100755 --- a/autotest/ogr/ogr_vrt.py +++ b/autotest/ogr/ogr_vrt.py @@ -3361,3 +3361,29 @@ def test_ogr_vrt_geom_coordinate_precision(): assert prec.GetXYResolution() == 1e-5 assert prec.GetZResolution() == 1e-3 assert prec.GetMResolution() == 1e-2 + + +############################################################################### +# Test OGRWarpedLayer and GetArrowStream + + +@pytest.mark.require_driver("GPKG") +def test_ogr_vrt_warped_arrow(tmp_vsimem): + + src_ds = ogr.Open( + """ + + + data/gpkg/2d_envelope.gpkg + + EPSG:32631 + + """ + ) + out_filename = str(tmp_vsimem / "out.gpkg") + with gdal.config_option("OGR2OGR_USE_ARROW_API", "YES"): + gdal.VectorTranslate(out_filename, src_ds) + ds = ogr.Open(out_filename) + assert ds.GetLayer(0).GetExtent() == pytest.approx( + (166021.443080541, 500000, 0.0, 331593.179548329) + ) diff --git a/autotest/ogr/ogr_wasp.py b/autotest/ogr/ogr_wasp.py index c9fe25464f3c..9093fd59a766 100755 --- a/autotest/ogr/ogr_wasp.py +++ b/autotest/ogr/ogr_wasp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, Oslandia # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math diff --git a/autotest/ogr/ogr_wfs.py b/autotest/ogr/ogr_wfs.py index 7873234f9d2a..2908533afd09 100755 --- a/autotest/ogr/ogr_wfs.py +++ b/autotest/ogr/ogr_wfs.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -63,9 +47,13 @@ def ogr_wfs_init(): if gml_ds is None: pytest.skip("cannot read GML files") + vsimem_hidden_before = gdal.ReadDirRecursive("/vsimem/.#!HIDDEN!#.") + with gdal.config_option("CPL_CURL_ENABLE_VSIMEM", "YES"): yield + assert gdal.ReadDirRecursive("/vsimem/.#!HIDDEN!#.") == vsimem_hidden_before + @pytest.fixture( params=["NO", None], scope="module", ids=["without-streaming", "with-streaming"] diff --git a/autotest/ogr/ogr_xls.py b/autotest/ogr/ogr_xls.py index 4f5a0f262a02..fd61c88fcad8 100755 --- a/autotest/ogr/ogr_xls.py +++ b/autotest/ogr/ogr_xls.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/ogr/ogr_xlsx.py b/autotest/ogr/ogr_xlsx.py index 632df94bcfab..a4b8cc287935 100755 --- a/autotest/ogr/ogr_xlsx.py +++ b/autotest/ogr/ogr_xlsx.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -665,3 +649,16 @@ def test_ogr_xlsx_read_xml_prefix(): f = lyr.GetNextFeature() assert f["Col1"] == "foo" assert f["Col2"] == "bar" + + +############################################################################### +# Test reading a XLSX file with without "r" attribute + + +def test_ogr_xlsx_read_row_without_r_attribute(): + + ds = ogr.Open("data/xlsx/row_without_r_attribute.xlsx") + lyr = ds.GetLayer(0) + f = lyr.GetNextFeature() + assert f["ID"] == 1 + assert f["NAME"] == "TEST123" diff --git a/autotest/ogr/ogr_xodr.py b/autotest/ogr/ogr_xodr.py index 43259ad77eb1..fc823cd6f9cb 100644 --- a/autotest/ogr/ogr_xodr.py +++ b/autotest/ogr/ogr_xodr.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright 2024 German Aerospace Center (DLR), Institute of Transportation Systems # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest import pytest @@ -37,6 +21,19 @@ xodr_file = "data/xodr/5g_living_lab_A39_Wolfsburg-West.xodr" +def test_ogr_xodr_i_do_not_exist(): + + assert gdal.IdentifyDriverEx("i_do_not_exist.xodr") is None + + +def test_ogr_xodr_empty(): + + gdal.ErrorReset() + with ogr.Open("data/xodr/empty.xodr") as ds: + assert gdal.GetLastErrorMsg() == "" + assert ds.GetLayerCount() == 6 + + def test_ogr_xodr_test_ogrsf(): import test_cli_utilities diff --git a/autotest/ogr/ograpispy.py b/autotest/ogr/ograpispy.py index 25b4b2f38fa6..f1d77deb337c 100755 --- a/autotest/ogr/ograpispy.py +++ b/autotest/ogr/ograpispy.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/osr/osr_basic.py b/autotest/osr/osr_basic.py index d49aada966fd..c14da1d0b007 100755 --- a/autotest/osr/osr_basic.py +++ b/autotest/osr/osr_basic.py @@ -12,23 +12,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -2494,3 +2478,13 @@ def test_osr_basic_export_wkt_utm_south(): j = json.loads(srs.ExportToPROJJSON()) assert j["conversion"]["id"]["code"] == 16101 + + +############################################################################### + + +def test_osr_basic_GetAuthorityListFromDatabase(): + + ret = osr.GetAuthorityListFromDatabase() + assert "EPSG" in ret + assert "PROJ" in ret diff --git a/autotest/osr/osr_basic_subprocess.py b/autotest/osr/osr_basic_subprocess.py index ac872f4a454c..9c7712ad5b4d 100755 --- a/autotest/osr/osr_basic_subprocess.py +++ b/autotest/osr/osr_basic_subprocess.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/osr/osr_cf1.py b/autotest/osr/osr_cf1.py index 70f6e5f69f7a..8c672d26c553 100755 --- a/autotest/osr/osr_cf1.py +++ b/autotest/osr/osr_cf1.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_compd.py b/autotest/osr/osr_compd.py index 4f1e1b7010f6..854ebb783873 100755 --- a/autotest/osr/osr_compd.py +++ b/autotest/osr/osr_compd.py @@ -11,23 +11,7 @@ # Copyright (c) 2010, Frank Warmerdam # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/osr/osr_ct.py b/autotest/osr/osr_ct.py index 4b1d326d7227..a12c3675b768 100755 --- a/autotest/osr/osr_ct.py +++ b/autotest/osr/osr_ct.py @@ -12,23 +12,7 @@ # Copyright (c) 2009-2013, Even Rouault # Copyright (c) 2014, Google # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import math diff --git a/autotest/osr/osr_ct_proj.py b/autotest/osr/osr_ct_proj.py index 2232dd3a9f46..ae896689ad03 100755 --- a/autotest/osr/osr_ct_proj.py +++ b/autotest/osr/osr_ct_proj.py @@ -11,23 +11,7 @@ # Copyright (c) 2004, Frank Warmerdam # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/osr/osr_epsg.py b/autotest/osr/osr_epsg.py index e88e3ebb7e5a..0053cc91eec5 100755 --- a/autotest/osr/osr_epsg.py +++ b/autotest/osr/osr_epsg.py @@ -11,23 +11,7 @@ # Copyright (c) 2007, Frank Warmerdam # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_esri.py b/autotest/osr/osr_esri.py index c109d219e016..b439340bbb46 100755 --- a/autotest/osr/osr_esri.py +++ b/autotest/osr/osr_esri.py @@ -13,23 +13,7 @@ # Copyright (c) 2013, Kyle Shannon # Copyright (c) 2014, Google # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/osr/osr_micoordsys.py b/autotest/osr/osr_micoordsys.py index 9e18c2922b43..b79827fc8286 100755 --- a/autotest/osr/osr_micoordsys.py +++ b/autotest/osr/osr_micoordsys.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_ozi.py b/autotest/osr/osr_ozi.py index 04d821132829..356f1bcaf6fd 100755 --- a/autotest/osr/osr_ozi.py +++ b/autotest/osr/osr_ozi.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_pm.py b/autotest/osr/osr_pm.py index 778c8245d2fd..513bdff9bee8 100755 --- a/autotest/osr/osr_pm.py +++ b/autotest/osr/osr_pm.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2003, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_proj4.py b/autotest/osr/osr_proj4.py index 18cdeb1d3582..50932e4ec749 100755 --- a/autotest/osr/osr_proj4.py +++ b/autotest/osr/osr_proj4.py @@ -12,23 +12,7 @@ # Copyright (c) 2009-2013, Even Rouault # Copyright (c) 2014, Kyle Shannon # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/osr/osr_url.py b/autotest/osr/osr_url.py index 06ae66d3c392..17dc87c5f06d 100755 --- a/autotest/osr/osr_url.py +++ b/autotest/osr/osr_url.py @@ -10,23 +10,7 @@ # Copyright (c) 2007, Howard Butler # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import socket diff --git a/autotest/osr/osr_usgs.py b/autotest/osr/osr_usgs.py index 04d8da586e98..582886cfdf59 100755 --- a/autotest/osr/osr_usgs.py +++ b/autotest/osr/osr_usgs.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2004, Andrey Kiselev # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_validate.py b/autotest/osr/osr_validate.py index 640cf677f316..73a5f3c2020b 100755 --- a/autotest/osr/osr_validate.py +++ b/autotest/osr/osr_validate.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/osr/osr_xml.py b/autotest/osr/osr_xml.py index 41ef4d1377bf..9822297909f4 100755 --- a/autotest/osr/osr_xml.py +++ b/autotest/osr/osr_xml.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import re diff --git a/autotest/postinstall/test_gdal-config.sh b/autotest/postinstall/test_gdal-config.sh index 19a656ee04ae..e77088e12e7b 100755 --- a/autotest/postinstall/test_gdal-config.sh +++ b/autotest/postinstall/test_gdal-config.sh @@ -102,7 +102,7 @@ set -eu CXX="${CXX:-c++}" echo "Test that we can compile all headers with C++11 using ${CXX}" for i in $prefix/include/*.h; do - ${CXX} -std=c++11 -c $(${GDAL_CONFIG} --cflags) $i; + ${CXX} -Wall -Wpedantic -std=c++11 -c $(${GDAL_CONFIG} --cflags) $i; done echo "$ERRORS tests failed out of $NTESTS" diff --git a/autotest/pymod/gdaltest.py b/autotest/pymod/gdaltest.py index 1c1677a3164b..2a119424df1b 100755 --- a/autotest/pymod/gdaltest.py +++ b/autotest/pymod/gdaltest.py @@ -10,23 +10,7 @@ # Copyright (c) 2003, Frank Warmerdam # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import contextlib @@ -56,13 +40,11 @@ jp2ecw_drv = None jp2mrsid_drv = None jp2openjpeg_drv = None -jp2lura_drv = None jp2kak_drv_unregistered = False jpeg2000_drv_unregistered = False jp2ecw_drv_unregistered = False jp2mrsid_drv_unregistered = False jp2openjpeg_drv_unregistered = False -jp2lura_drv_unregistered = False ############################################################################### @@ -90,7 +72,7 @@ def testCreateCopyInterruptCallback(pct, message, user_data): ############################################################################### -class GDALTest(object): +class GDALTest: def __init__( self, drivername, @@ -1280,8 +1262,8 @@ def compare_ds(ds1, ds2, xoff=0, yoff=0, width=0, height=0, verbose=1): def deregister_all_jpeg2000_drivers_but(name_of_driver_to_keep): - global jp2kak_drv, jpeg2000_drv, jp2ecw_drv, jp2mrsid_drv, jp2openjpeg_drv, jp2lura_drv - global jp2kak_drv_unregistered, jpeg2000_drv_unregistered, jp2ecw_drv_unregistered, jp2mrsid_drv_unregistered, jp2openjpeg_drv_unregistered, jp2lura_drv_unregistered + global jp2kak_drv, jpeg2000_drv, jp2ecw_drv, jp2mrsid_drv, jp2openjpeg_drv + global jp2kak_drv_unregistered, jpeg2000_drv_unregistered, jp2ecw_drv_unregistered, jp2mrsid_drv_unregistered, jp2openjpeg_drv_unregistered # Deregister other potential conflicting JPEG2000 drivers that will # be re-registered in the cleanup @@ -1315,12 +1297,6 @@ def deregister_all_jpeg2000_drivers_but(name_of_driver_to_keep): jp2openjpeg_drv.Deregister() jp2openjpeg_drv_unregistered = True - jp2lura_drv = gdal.GetDriverByName("JP2Lura") - if name_of_driver_to_keep != "JP2Lura" and jp2lura_drv: - gdal.Debug("gdaltest.", "Deregistering JP2Lura") - jp2lura_drv.Deregister() - jp2lura_drv_unregistered = True - return True @@ -1330,8 +1306,8 @@ def deregister_all_jpeg2000_drivers_but(name_of_driver_to_keep): def reregister_all_jpeg2000_drivers(): - global jp2kak_drv, jpeg2000_drv, jp2ecw_drv, jp2mrsid_drv, jp2openjpeg_drv, jp2lura_drv - global jp2kak_drv_unregistered, jpeg2000_drv_unregistered, jp2ecw_drv_unregistered, jp2mrsid_drv_unregistered, jp2openjpeg_drv_unregistered, jp2lura_drv_unregistered + global jp2kak_drv, jpeg2000_drv, jp2ecw_drv, jp2mrsid_drv, jp2openjpeg_drv + global jp2kak_drv_unregistered, jpeg2000_drv_unregistered, jp2ecw_drv_unregistered, jp2mrsid_drv_unregistered, jp2openjpeg_drv_unregistered if jp2kak_drv_unregistered: jp2kak_drv.Register() @@ -1358,11 +1334,6 @@ def reregister_all_jpeg2000_drivers(): jp2openjpeg_drv_unregistered = False gdal.Debug("gdaltest", "Registering JP2OpenJPEG") - if jp2lura_drv_unregistered: - jp2lura_drv.Register() - jp2lura_drv_unregistered = False - gdal.Debug("gdaltest", "Registering JP2Lura") - return True @@ -2118,84 +2089,10 @@ def reopen(ds, update=False, open_options=None): ) -# VSIFile helper class - - -class VSIFile: - def __init__(self, path, mode, encoding="utf-8"): - self._path = path - self._mode = mode - - self._binary = "b" in mode - self._encoding = encoding - - self._fp = gdal.VSIFOpenExL(self._path, self._mode, True) - if self._fp is None: - raise OSError(gdal.VSIGetLastErrorMsg()) - - self._closed = False - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def __iter__(self): - return self - - def __next__(self): - line = gdal.CPLReadLineL(self._fp) - if line is None: - raise StopIteration - if self._binary: - return line.encode() - return line - - def close(self): - if self._closed: - return - - self._closed = True - gdal.VSIFCloseL(self._fp) - - def read(self, size=-1): - if size == -1: - pos = self.tell() - self.seek(0, 2) - size = self.tell() - self.seek(pos) - - raw = gdal.VSIFReadL(1, size, self._fp) - - if self._binary: - return bytes(raw) - else: - return raw.decode(self._encoding) - - def write(self, x): - - if self._binary: - assert type(x) in (bytes, bytearray, memoryview) - else: - assert type(x) is str - x = x.encode(self._encoding) - - planned_write = len(x) - actual_write = gdal.VSIFWriteL(x, 1, planned_write, self._fp) - - if planned_write != actual_write: - raise OSError( - f"Expected to write {planned_write} bytes but {actual_write} were written" - ) - - def seek(self, offset, whence=0): - if gdal.VSIFSeekL(self._fp, offset, whence) != 0: - raise OSError(gdal.VSIGetLastErrorMsg()) - - def tell(self): - return gdal.VSIFTellL(self._fp) +def vsi_open(path, mode="r"): + return gdal.VSIFile(path, mode) -def vsi_open(path, mode="r"): - return VSIFile(path, mode) +def vrt_has_open_support(): + drv = gdal.GetDriverByName("VRT") + return drv is not None and drv.GetMetadataItem(gdal.DMD_OPENOPTIONLIST) is not None diff --git a/autotest/pymod/test_cli_utilities.py b/autotest/pymod/test_cli_utilities.py index 9a8251d4ff4e..57864cab5ed0 100755 --- a/autotest/pymod/test_cli_utilities.py +++ b/autotest/pymod/test_cli_utilities.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -224,6 +208,14 @@ def get_gdaldem_path(): # +def get_gdalenhance_path(): + return get_cli_utility_path("gdalenhance") + + +############################################################################### +# + + def get_gdal_rasterize_path(): return get_cli_utility_path("gdal_rasterize") diff --git a/autotest/pymod/test_py_scripts.py b/autotest/pymod/test_py_scripts.py index 26d703a6e6d0..21a4aa99c95b 100755 --- a/autotest/pymod/test_py_scripts.py +++ b/autotest/pymod/test_py_scripts.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import importlib diff --git a/autotest/pymod/uffd.py b/autotest/pymod/uffd.py index f2614f42b3b7..74ee71341de2 100755 --- a/autotest/pymod/uffd.py +++ b/autotest/pymod/uffd.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2018, Dr. James McClain # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pymod/webserver.py b/autotest/pymod/webserver.py index 4207b518ba31..e619a097c6c6 100755 --- a/autotest/pymod/webserver.py +++ b/autotest/pymod/webserver.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import contextlib @@ -55,7 +39,7 @@ def install_http_handler(handler_instance): custom_handler = None -class RequestResponse(object): +class RequestResponse: def __init__( self, method, @@ -92,7 +76,7 @@ def __repr__(self): ) -class FileHandler(object): +class FileHandler: """ Handler that serves files from a dictionary and/or a fallback VSI location. """ @@ -213,7 +197,7 @@ def do_DELETE(self, request): self.send_response(request, filedata) -class BaseMockedHttpHandler(object): +class BaseMockedHttpHandler: @staticmethod def _process_req_resp(req_resp, request): if req_resp.custom_method: diff --git a/autotest/pymod/xmlvalidate.py b/autotest/pymod/xmlvalidate.py index e7be16cdbdb0..f53eedd1d517 100755 --- a/autotest/pymod/xmlvalidate.py +++ b/autotest/pymod/xmlvalidate.py @@ -11,23 +11,7 @@ # ( https://github.com/EOxServer/eoxserver/blob/master/eoxserver/services/testbase.py ) # Copyright (C) 2011 EOX IT Services GmbH # -# 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 of this Software or works derived from this 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/gdal2tiles/test_add_alpha_band_to_string_vrt.py b/autotest/pyscripts/gdal2tiles/test_add_alpha_band_to_string_vrt.py index 659362191f44..913658e522c4 100644 --- a/autotest/pyscripts/gdal2tiles/test_add_alpha_band_to_string_vrt.py +++ b/autotest/pyscripts/gdal2tiles/test_add_alpha_band_to_string_vrt.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/gdal2tiles/test_add_gdal_warp_options_to_string.py b/autotest/pyscripts/gdal2tiles/test_add_gdal_warp_options_to_string.py index e565535b2255..be4e762bbcba 100644 --- a/autotest/pyscripts/gdal2tiles/test_add_gdal_warp_options_to_string.py +++ b/autotest/pyscripts/gdal2tiles/test_add_gdal_warp_options_to_string.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/gdal2tiles/test_logger.py b/autotest/pyscripts/gdal2tiles/test_logger.py index de9cd087b1bd..ca32fd84d68b 100644 --- a/autotest/pyscripts/gdal2tiles/test_logger.py +++ b/autotest/pyscripts/gdal2tiles/test_logger.py @@ -10,30 +10,20 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import gdaltest import pytest from osgeo import gdal from osgeo_utils import gdal2tiles +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + def test_gdal2tiles_logger(): diff --git a/autotest/pyscripts/gdal2tiles/test_nb_data_bands.py b/autotest/pyscripts/gdal2tiles/test_nb_data_bands.py index cef8de5a1f33..21db8db7fd20 100644 --- a/autotest/pyscripts/gdal2tiles/test_nb_data_bands.py +++ b/autotest/pyscripts/gdal2tiles/test_nb_data_bands.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from unittest import TestCase, mock diff --git a/autotest/pyscripts/gdal2tiles/test_option_parser.py b/autotest/pyscripts/gdal2tiles/test_option_parser.py index bc13f199ded6..f6fecc232197 100644 --- a/autotest/pyscripts/gdal2tiles/test_option_parser.py +++ b/autotest/pyscripts/gdal2tiles/test_option_parser.py @@ -11,23 +11,7 @@ # Copyright (c) 2017, Gregory Bataille # Copyright (c) 2021, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/gdal2tiles/test_reproject_dataset.py b/autotest/pyscripts/gdal2tiles/test_reproject_dataset.py index 5ada942f957a..43318166be37 100644 --- a/autotest/pyscripts/gdal2tiles/test_reproject_dataset.py +++ b/autotest/pyscripts/gdal2tiles/test_reproject_dataset.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from unittest import TestCase, mock diff --git a/autotest/pyscripts/gdal2tiles/test_setup_input_srs.py b/autotest/pyscripts/gdal2tiles/test_setup_input_srs.py index a4685af2c7f4..a8905b403e98 100644 --- a/autotest/pyscripts/gdal2tiles/test_setup_input_srs.py +++ b/autotest/pyscripts/gdal2tiles/test_setup_input_srs.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from unittest import TestCase, mock diff --git a/autotest/pyscripts/gdal2tiles/test_setup_no_data_value.py b/autotest/pyscripts/gdal2tiles/test_setup_no_data_value.py index afe6b3af6874..c41a07e8c860 100644 --- a/autotest/pyscripts/gdal2tiles/test_setup_no_data_value.py +++ b/autotest/pyscripts/gdal2tiles/test_setup_no_data_value.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from unittest import TestCase, mock diff --git a/autotest/pyscripts/gdal2tiles/test_update_alpha_value_for_non_alpha_inputs.py b/autotest/pyscripts/gdal2tiles/test_update_alpha_value_for_non_alpha_inputs.py index 3c1e74763966..29ea02992966 100644 --- a/autotest/pyscripts/gdal2tiles/test_update_alpha_value_for_non_alpha_inputs.py +++ b/autotest/pyscripts/gdal2tiles/test_update_alpha_value_for_non_alpha_inputs.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2017, Gregory Bataille # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### from unittest import TestCase, mock diff --git a/autotest/pyscripts/gdal2tiles/test_vsimem.py b/autotest/pyscripts/gdal2tiles/test_vsimem.py index 340e0238f7c4..f09b3825e2fc 100644 --- a/autotest/pyscripts/gdal2tiles/test_vsimem.py +++ b/autotest/pyscripts/gdal2tiles/test_vsimem.py @@ -10,30 +10,20 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import gdaltest import pytest from osgeo import gdal from osgeo_utils import gdal2tiles +pytestmark = pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) + def test_gdal2tiles_vsimem(): diff --git a/autotest/pyscripts/test_gdal2tiles.py b/autotest/pyscripts/test_gdal2tiles.py index b3da97a4de72..e4012ce41468 100755 --- a/autotest/pyscripts/test_gdal2tiles.py +++ b/autotest/pyscripts/test_gdal2tiles.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import glob @@ -43,10 +27,15 @@ from osgeo import gdal, osr # noqa from osgeo_utils.gdalcompare import compare_db -pytestmark = pytest.mark.skipif( - test_py_scripts.get_py_script("gdal2tiles") is None, - reason="gdal2tiles not available", -) +pytestmark = [ + pytest.mark.skipif( + test_py_scripts.get_py_script("gdal2tiles") is None, + reason="gdal2tiles not available", + ), + pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), reason="VRT driver open missing" + ), +] @pytest.fixture() diff --git a/autotest/pyscripts/test_gdal2xyz.py b/autotest/pyscripts/test_gdal2xyz.py index 85f71bc6a2c3..f67771ec9b9f 100644 --- a/autotest/pyscripts/test_gdal2xyz.py +++ b/autotest/pyscripts/test_gdal2xyz.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/test_gdal_calc.py b/autotest/pyscripts/test_gdal_calc.py index c7259fb2a4c5..3b10b9b8a392 100755 --- a/autotest/pyscripts/test_gdal_calc.py +++ b/autotest/pyscripts/test_gdal_calc.py @@ -12,23 +12,7 @@ # Copyright (c) 2014, Etienne Tourigny # Copyright (c) 2020, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/test_gdal_edit.py b/autotest/pyscripts/test_gdal_edit.py index 4d29819a9bbe..8f5adbda27a7 100755 --- a/autotest/pyscripts/test_gdal_edit.py +++ b/autotest/pyscripts/test_gdal_edit.py @@ -10,29 +10,14 @@ ############################################################################### # Copyright (c) 2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os import shutil import sys +import gdaltest import pytest import test_py_scripts @@ -62,6 +47,9 @@ def script_path(): def test_gdal_edit_help(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdal_edit", "--help" ) @@ -73,6 +61,9 @@ def test_gdal_edit_help(script_path): def test_gdal_edit_version(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdal_edit", "--version" ) diff --git a/autotest/pyscripts/test_gdal_fillnodata.py b/autotest/pyscripts/test_gdal_fillnodata.py index eac38284187d..b24323242393 100755 --- a/autotest/pyscripts/test_gdal_fillnodata.py +++ b/autotest/pyscripts/test_gdal_fillnodata.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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, fillnodata, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/pyscripts/test_gdal_ls_py.py b/autotest/pyscripts/test_gdal_ls_py.py index 3eb86e12a0b3..54b03771de05 100755 --- a/autotest/pyscripts/test_gdal_ls_py.py +++ b/autotest/pyscripts/test_gdal_ls_py.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import io diff --git a/autotest/pyscripts/test_gdal_merge.py b/autotest/pyscripts/test_gdal_merge.py index 4b1372efb3fa..ab39d60ea2f3 100755 --- a/autotest/pyscripts/test_gdal_merge.py +++ b/autotest/pyscripts/test_gdal_merge.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/pyscripts/test_gdal_pansharpen.py b/autotest/pyscripts/test_gdal_pansharpen.py index 160b68879b94..584f9d9b81ea 100755 --- a/autotest/pyscripts/test_gdal_pansharpen.py +++ b/autotest/pyscripts/test_gdal_pansharpen.py @@ -10,26 +10,10 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### - +import gdaltest import pytest import test_py_scripts @@ -95,6 +79,10 @@ def test_gdal_pansharpen_version(script_path): # Simple test +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_pansharpen_1(script_path, tmp_path, small_world_pan_tif): out_tif = str(tmp_path / "out.tif") @@ -120,6 +108,10 @@ def test_gdal_pansharpen_1(script_path, tmp_path, small_world_pan_tif): # Full options +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_pansharpen_2(script_path, tmp_path, small_world_pan_tif): out_vrt = str(tmp_path / "out.vrt") diff --git a/autotest/pyscripts/test_gdal_polygonize.py b/autotest/pyscripts/test_gdal_polygonize.py index 90eec0de5b96..4319d29aa739 100755 --- a/autotest/pyscripts/test_gdal_polygonize.py +++ b/autotest/pyscripts/test_gdal_polygonize.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -263,6 +247,7 @@ def test_gdal_polygonize_4bis(script_path, tmp_path): # Test -8 +@pytest.mark.require_driver("GeoJSON") def test_gdal_polygonize_minus_8(script_path, tmp_path): outfilename = str(tmp_path / "out.geojson") diff --git a/autotest/pyscripts/test_gdal_proximity.py b/autotest/pyscripts/test_gdal_proximity.py index 059e84a538a9..a09ce5a4e461 100755 --- a/autotest/pyscripts/test_gdal_proximity.py +++ b/autotest/pyscripts/test_gdal_proximity.py @@ -10,25 +10,10 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import gdaltest import pytest import test_py_scripts @@ -51,6 +36,9 @@ def script_path(): def test_gdal_proximity_help(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdal_proximity", "--help" ) @@ -62,6 +50,9 @@ def test_gdal_proximity_help(script_path): def test_gdal_proximity_version(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdal_proximity", "--version" ) diff --git a/autotest/pyscripts/test_gdal_retile.py b/autotest/pyscripts/test_gdal_retile.py index 76e5a54ef6df..25c1359862d3 100755 --- a/autotest/pyscripts/test_gdal_retile.py +++ b/autotest/pyscripts/test_gdal_retile.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import glob diff --git a/autotest/pyscripts/test_gdal_sieve.py b/autotest/pyscripts/test_gdal_sieve.py index 2e635a457049..e61699f159dc 100755 --- a/autotest/pyscripts/test_gdal_sieve.py +++ b/autotest/pyscripts/test_gdal_sieve.py @@ -10,23 +10,7 @@ # Copyright (c) 2008, Frank Warmerdam # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/pyscripts/test_gdal_utils.py b/autotest/pyscripts/test_gdal_utils.py index f7062574d174..5e758def3391 100644 --- a/autotest/pyscripts/test_gdal_utils.py +++ b/autotest/pyscripts/test_gdal_utils.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import array diff --git a/autotest/pyscripts/test_gdal_utils_cli.py b/autotest/pyscripts/test_gdal_utils_cli.py index 2922071399c4..c9ff105df39f 100644 --- a/autotest/pyscripts/test_gdal_utils_cli.py +++ b/autotest/pyscripts/test_gdal_utils_cli.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, Matt Wilkie # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### """ Test that command line gdal-utils are in PATH and run. We only test script diff --git a/autotest/pyscripts/test_gdal_utils_retcodes.py b/autotest/pyscripts/test_gdal_utils_retcodes.py index 30c9466ad939..97fb1289619d 100644 --- a/autotest/pyscripts/test_gdal_utils_retcodes.py +++ b/autotest/pyscripts/test_gdal_utils_retcodes.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, Matt Wilkie # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### """ Verify that gdal-utils scripts all exit with the same return code when diff --git a/autotest/pyscripts/test_gdalattachpct.py b/autotest/pyscripts/test_gdalattachpct.py index d81b173eadc4..6954b55444f3 100755 --- a/autotest/pyscripts/test_gdalattachpct.py +++ b/autotest/pyscripts/test_gdalattachpct.py @@ -9,25 +9,10 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import gdaltest import pytest import test_py_scripts @@ -91,6 +76,10 @@ def test_gdalattachpct_basic(script_path, tmp_path, palette_file): # Test outputting to VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalattachpct_vrt_output(script_path, tmp_path, palette_file): src_filename = str(tmp_path / "src.tif") diff --git a/autotest/pyscripts/test_gdalbuildvrtofvrt.py b/autotest/pyscripts/test_gdalbuildvrtofvrt.py index 19630a21727a..db3001f3a618 100755 --- a/autotest/pyscripts/test_gdalbuildvrtofvrt.py +++ b/autotest/pyscripts/test_gdalbuildvrtofvrt.py @@ -9,27 +9,12 @@ ############################################################################### # Copyright (c) 2024, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os +import gdaltest import pytest import test_py_scripts @@ -41,6 +26,9 @@ test_py_scripts.get_py_script("gdalbuildvrtofvrt") is None, reason="gdalbuildvrtofvrt.py not available", ), + pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), reason="VRT driver open missing" + ), ] diff --git a/autotest/pyscripts/test_gdalcompare.py b/autotest/pyscripts/test_gdalcompare.py index bfa928f952a1..1a021580202a 100644 --- a/autotest/pyscripts/test_gdalcompare.py +++ b/autotest/pyscripts/test_gdalcompare.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil diff --git a/autotest/pyscripts/test_gdalinfo_py.py b/autotest/pyscripts/test_gdalinfo_py.py index 235b40dbdc29..b5527c71d371 100755 --- a/autotest/pyscripts/test_gdalinfo_py.py +++ b/autotest/pyscripts/test_gdalinfo_py.py @@ -9,28 +9,13 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os import shutil +import gdaltest import pytest import test_py_scripts @@ -140,6 +125,7 @@ def test_gdalinfo_py_5(script_path): # Test a dataset with overviews and RAT +@pytest.mark.require_driver("HFA") def test_gdalinfo_py_6(script_path): ret = test_py_scripts.run_py_script( @@ -154,6 +140,10 @@ def test_gdalinfo_py_6(script_path): # Test a dataset with GCPs +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalinfo_py_7(script_path): ret = test_py_scripts.run_py_script( diff --git a/autotest/pyscripts/test_gdallocationinfo_py.py b/autotest/pyscripts/test_gdallocationinfo_py.py index 0a034f1c5904..3ca9312ece20 100644 --- a/autotest/pyscripts/test_gdallocationinfo_py.py +++ b/autotest/pyscripts/test_gdallocationinfo_py.py @@ -11,23 +11,7 @@ # Copyright (c) 2010-2013, Even Rouault # Copyright (c) 2021, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/pyscripts/test_gdalmove.py b/autotest/pyscripts/test_gdalmove.py index 296ebee3c08d..84080916d47f 100755 --- a/autotest/pyscripts/test_gdalmove.py +++ b/autotest/pyscripts/test_gdalmove.py @@ -9,27 +9,12 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil +import gdaltest import pytest import test_py_scripts @@ -52,6 +37,9 @@ def script_path(): def test_gdalmove_help(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdalmove", "--help" ) @@ -63,6 +51,9 @@ def test_gdalmove_help(script_path): def test_gdalmove_version(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "gdalmove", "--version" ) diff --git a/autotest/pyscripts/test_ogr_layer_algebra.py b/autotest/pyscripts/test_ogr_layer_algebra.py index ca6188b68da0..2a16fc5412ef 100644 --- a/autotest/pyscripts/test_ogr_layer_algebra.py +++ b/autotest/pyscripts/test_ogr_layer_algebra.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2022, Radha Krishna Kavuluru # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import ogrtest diff --git a/autotest/pyscripts/test_ogrinfo_py.py b/autotest/pyscripts/test_ogrinfo_py.py index 6ef7aa74b3ba..7be7d6546465 100755 --- a/autotest/pyscripts/test_ogrinfo_py.py +++ b/autotest/pyscripts/test_ogrinfo_py.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/pyscripts/test_ogrmerge.py b/autotest/pyscripts/test_ogrmerge.py index b8f30feabbbf..e6600485e86c 100755 --- a/autotest/pyscripts/test_ogrmerge.py +++ b/autotest/pyscripts/test_ogrmerge.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2017, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys @@ -36,10 +20,13 @@ from osgeo import gdal, ogr -pytestmark = pytest.mark.skipif( - test_py_scripts.get_py_script("ogrmerge") is None, - reason="ogrmerge.py not available", -) +pytestmark = [ + pytest.mark.require_driver("OGR_VRT"), + pytest.mark.skipif( + test_py_scripts.get_py_script("ogrmerge") is None, + reason="ogrmerge.py not available", + ), +] @pytest.fixture() diff --git a/autotest/pyscripts/test_osr_util.py b/autotest/pyscripts/test_osr_util.py index 529c2f90ecd2..bd174fce6c92 100644 --- a/autotest/pyscripts/test_osr_util.py +++ b/autotest/pyscripts/test_osr_util.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2021, Idan Miara # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import pytest diff --git a/autotest/pyscripts/test_pct.py b/autotest/pyscripts/test_pct.py index c85ab2c76c93..c549685ea5ff 100755 --- a/autotest/pyscripts/test_pct.py +++ b/autotest/pyscripts/test_pct.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2010, 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -56,6 +40,9 @@ def script_path(): def test_rgb2pct_help(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "rgb2pct", "--help" ) @@ -67,6 +54,9 @@ def test_rgb2pct_help(script_path): def test_rgb2pct_version(script_path): + if gdaltest.is_travis_branch("sanitize"): + pytest.skip("fails on sanitize for unknown reason") + assert "ERROR" not in test_py_scripts.run_py_script( script_path, "rgb2pct", "--version" ) @@ -248,6 +238,7 @@ def test_rgb2pct_3(script_path, tmp_path, rgb2pct2_tif): # Test pct2rgb with big CT (>256 entries) +@pytest.mark.require_driver("HFA") def test_pct2rgb_4(script_path, tmp_path): gdal_array = pytest.importorskip("osgeo.gdal_array") try: diff --git a/autotest/pyscripts/test_validate_geoparquet.py b/autotest/pyscripts/test_validate_geoparquet.py index 25343f6abedc..b29c6b70cc2c 100755 --- a/autotest/pyscripts/test_validate_geoparquet.py +++ b/autotest/pyscripts/test_validate_geoparquet.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json diff --git a/autotest/slow_tests/raster.py b/autotest/slow_tests/raster.py index c96198b55f33..e6927afa5ff8 100644 --- a/autotest/slow_tests/raster.py +++ b/autotest/slow_tests/raster.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/test_random_tiff.py b/autotest/test_random_tiff.py index 1f5d47de923d..8115fa3b27da 100755 --- a/autotest/test_random_tiff.py +++ b/autotest/test_random_tiff.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2012, 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. +# SPDX-License-Identifier: MIT ############################################################################### import random diff --git a/autotest/utilities/data/geog_arc_second.tif b/autotest/utilities/data/geog_arc_second.tif new file mode 100644 index 000000000000..19c84cabfdbc Binary files /dev/null and b/autotest/utilities/data/geog_arc_second.tif differ diff --git a/autotest/utilities/test_gdal_contour.py b/autotest/utilities/test_gdal_contour.py index 6be883a1afb2..c46f277afa2e 100755 --- a/autotest/utilities/test_gdal_contour.py +++ b/autotest/utilities/test_gdal_contour.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct @@ -128,34 +112,33 @@ def test_gdal_contour_1(gdal_contour_path, testdata_tif, tmp_path): ] expected_height = [0, 10, 20] - lyr = ds.ExecuteSQL("select * from contour order by elev asc") + with ds.ExecuteSQL("select * from contour order by elev asc") as lyr: - raster_srs_wkt = gdal.Open(testdata_tif).GetSpatialRef().ExportToWkt() + raster_srs_wkt = gdal.Open(testdata_tif).GetSpatialRef().ExportToWkt() - assert ( - lyr.GetSpatialRef().ExportToWkt() == raster_srs_wkt - ), "Did not get expected spatial ref" + assert ( + lyr.GetSpatialRef().ExportToWkt() == raster_srs_wkt + ), "Did not get expected spatial ref" - assert lyr.GetFeatureCount() == len(expected_envelopes) + assert lyr.GetFeatureCount() == len(expected_envelopes) - size = 160 - precision = 1.0 / size - - i = 0 - for feat in lyr: - geom = feat.GetGeometryRef() - envelope = geom.GetEnvelope() - assert feat.GetField("elev") == expected_height[i] - for j in range(4): - if expected_envelopes[i][j] != pytest.approx(envelope[j], rel=1e-8): - print("i=%d, wkt=%s" % (i, geom.ExportToWkt())) - print(geom.GetEnvelope()) - pytest.fail( - "%f, %f" % (expected_envelopes[i][j] - envelope[j], precision / 2) - ) - i = i + 1 + size = 160 + precision = 1.0 / size - ds.ReleaseResultSet(lyr) + i = 0 + for feat in lyr: + geom = feat.GetGeometryRef() + envelope = geom.GetEnvelope() + assert feat.GetField("elev") == expected_height[i] + for j in range(4): + if expected_envelopes[i][j] != pytest.approx(envelope[j], rel=1e-8): + print("i=%d, wkt=%s" % (i, geom.ExportToWkt())) + print(geom.GetEnvelope()) + pytest.fail( + "%f, %f" + % (expected_envelopes[i][j] - envelope[j], precision / 2) + ) + i = i + 1 ############################################################################### @@ -189,29 +172,28 @@ def test_gdal_contour_2(gdal_contour_path, testdata_tif, tmp_path): ] expected_height = [10, 20, 25] - lyr = ds.ExecuteSQL("select * from contour order by elev asc") - - assert lyr.GetFeatureCount() == len(expected_envelopes) - - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetGeometryRef().GetZ(0) == expected_height[i] - envelope = feat.GetGeometryRef().GetEnvelope() - assert feat.GetField("elev") == expected_height[i] - for j in range(4): - if expected_envelopes[i][j] != pytest.approx( - envelope[j], abs=precision / 2 * 1.001 - ): - print("i=%d, wkt=%s" % (i, feat.GetGeometryRef().ExportToWkt())) - print(feat.GetGeometryRef().GetEnvelope()) - pytest.fail( - "%f, %f" % (expected_envelopes[i][j] - envelope[j], precision / 2) - ) - i = i + 1 - feat = lyr.GetNextFeature() + with ds.ExecuteSQL("select * from contour order by elev asc") as lyr: + + assert lyr.GetFeatureCount() == len(expected_envelopes) - ds.ReleaseResultSet(lyr) + i = 0 + feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetGeometryRef().GetZ(0) == expected_height[i] + envelope = feat.GetGeometryRef().GetEnvelope() + assert feat.GetField("elev") == expected_height[i] + for j in range(4): + if expected_envelopes[i][j] != pytest.approx( + envelope[j], abs=precision / 2 * 1.001 + ): + print("i=%d, wkt=%s" % (i, feat.GetGeometryRef().ExportToWkt())) + print(feat.GetGeometryRef().GetEnvelope()) + pytest.fail( + "%f, %f" + % (expected_envelopes[i][j] - envelope[j], precision / 2) + ) + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -229,19 +211,17 @@ def test_gdal_contour_3(gdal_contour_path, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select distinct elev from contour order by elev asc") + with ds.ExecuteSQL("select distinct elev from contour order by elev asc") as lyr: - expected_heights = [100, 150, 200, 250, 300, 350, 400, 450] - assert lyr.GetFeatureCount() == len(expected_heights) + expected_heights = [100, 150, 200, 250, 300, 350, 400, 450] + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - i = i + 1 + i = 0 feat = lyr.GetNextFeature() - - ds.ReleaseResultSet(lyr) + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -418,18 +398,18 @@ def test_gdal_contour_fl_and_i(gdal_contour_path, testdata_tif, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev from contour order by elev asc") + with ds.ExecuteSQL("select elev from contour order by elev asc") as lyr: - expected_heights = [0, 6, 10, 16, 20] + expected_heights = [0, 6, 10, 16, 20] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -447,18 +427,18 @@ def test_gdal_contour_fl_e(gdal_contour_path, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select distinct elev from contour order by elev asc") + with ds.ExecuteSQL("select distinct elev from contour order by elev asc") as lyr: - expected_heights = [76, 81, 112, 243, 441] + expected_heights = [76, 81, 112, 243, 441] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -478,18 +458,18 @@ def test_gdal_contour_fl_ignore_off(gdal_contour_path, testdata_tif, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev from contour order by elev asc") + with ds.ExecuteSQL("select elev from contour order by elev asc") as lyr: - expected_heights = [2, 6, 12, 16, 22] + expected_heights = [2, 6, 12, 16, 22] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -508,18 +488,18 @@ def test_gdal_contour_fl_and_i_no_dups(gdal_contour_path, testdata_tif, tmp_path ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev from contour order by elev asc") + with ds.ExecuteSQL("select elev from contour order by elev asc") as lyr: - expected_heights = [0, 6, 10, 16, 20] + expected_heights = [0, 6, 10, 16, 20] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -539,20 +519,20 @@ def test_gdal_contour_i_polygonize(gdal_contour_path, testdata_tif, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") + with ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") as lyr: - # Raster max is 25 so the last contour is 20 (with amax of 25) - expected_heights = [0, 5, 10, 15, 20] + # Raster max is 25 so the last contour is 20 (with amax of 25) + expected_heights = [0, 5, 10, 15, 20] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - assert feat.GetField("elev2") == expected_heights[i] + 5 - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + assert feat.GetField("elev2") == expected_heights[i] + 5 + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -575,24 +555,24 @@ def test_gdal_contour_fl_and_i_no_dups_polygonize( ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") + with ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") as lyr: - # Raster max is 25 so the last contour is 20 (with amax of 25) - expected_heights = [0, 5, 6, 10, 15, 16, 20] + # Raster max is 25 so the last contour is 20 (with amax of 25) + expected_heights = [0, 5, 6, 10, 15, 16, 20] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - assert ( - feat.GetField("elev2") == expected_heights[i + 1] - if i < len(expected_heights) - 2 - else expected_heights[i] + 5 - ) - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + assert ( + feat.GetField("elev2") == expected_heights[i + 1] + if i < len(expected_heights) - 2 + else expected_heights[i] + 5 + ) + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -610,24 +590,24 @@ def test_gdal_contour_fl_e_polygonize(gdal_contour_path, tmp_path): ds = ogr.Open(contour_shp) - lyr = ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") + with ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") as lyr: - # Raster min is 75, max is 460 - expected_heights = [75, 76, 81, 112, 243, 441] + # Raster min is 75, max is 460 + expected_heights = [75, 76, 81, 112, 243, 441] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) - i = 0 - feat = lyr.GetNextFeature() - while feat is not None: - assert feat.GetField("elev") == expected_heights[i] - assert ( - feat.GetField("elev2") == expected_heights[i + 1] - if i < len(expected_heights) - 2 - else 460 - ) - i = i + 1 + i = 0 feat = lyr.GetNextFeature() + while feat is not None: + assert feat.GetField("elev") == expected_heights[i] + assert ( + feat.GetField("elev2") == expected_heights[i + 1] + if i < len(expected_heights) - 2 + else 460 + ) + i = i + 1 + feat = lyr.GetNextFeature() ############################################################################### @@ -647,9 +627,9 @@ def test_gdal_contour_gt(gdal_contour_path, tmp_path, gt): ds = ogr.Open(out_filename) - lyr = ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") + with ds.ExecuteSQL("select elev, elev2 from contour order by elev asc") as lyr: - # Raster min is 75, max is 460 - expected_heights = [75, 76, 81, 112, 243, 441] + # Raster min is 75, max is 460 + expected_heights = [75, 76, 81, 112, 243, 441] - assert lyr.GetFeatureCount() == len(expected_heights) + assert lyr.GetFeatureCount() == len(expected_heights) diff --git a/autotest/utilities/test_gdal_create.py b/autotest/utilities/test_gdal_create.py index 13c26b7fb58d..7e50e54df7f8 100755 --- a/autotest/utilities/test_gdal_create.py +++ b/autotest/utilities/test_gdal_create.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -222,6 +206,10 @@ def test_gdal_create_input_file_overrrides(gdal_create_path, tmp_path): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_create_input_file_gcps(gdal_create_path, tmp_path): output_tif = str(tmp_path / "tmp.tif") diff --git a/autotest/utilities/test_gdal_footprint.py b/autotest/utilities/test_gdal_footprint.py index 75661c891056..bb24662d55f4 100755 --- a/autotest/utilities/test_gdal_footprint.py +++ b/autotest/utilities/test_gdal_footprint.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -53,6 +37,7 @@ def gdal_footprint_path(): ############################################################################### +@pytest.mark.require_driver("GeoJSON") def test_gdal_footprint_basic(gdal_footprint_path, tmp_path): footprint_json = str(tmp_path / "out_footprint.json") diff --git a/autotest/utilities/test_gdal_footprint_lib.py b/autotest/utilities/test_gdal_footprint_lib.py index d8a969b887e5..2b80576444c4 100755 --- a/autotest/utilities/test_gdal_footprint_lib.py +++ b/autotest/utilities/test_gdal_footprint_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -123,6 +107,7 @@ def test_gdal_footprint_lib_destSRS(): # +@pytest.mark.require_driver("GeoJSON") def test_gdal_footprint_lib_inline_geojson(): ret = gdal.Footprint("", "../gcore/data/byte.tif", format="GeoJSON") @@ -134,6 +119,7 @@ def test_gdal_footprint_lib_inline_geojson(): # +@pytest.mark.require_driver("GeoJSON") def test_gdal_footprint_lib_inline_wkt(): ret = gdal.Footprint("", "../gcore/data/byte.tif", format="WKT") diff --git a/autotest/utilities/test_gdal_grid.py b/autotest/utilities/test_gdal_grid.py index 554e95395855..48ebb0a0a9d7 100755 --- a/autotest/utilities/test_gdal_grid.py +++ b/autotest/utilities/test_gdal_grid.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import struct diff --git a/autotest/utilities/test_gdal_grid_lib.py b/autotest/utilities/test_gdal_grid_lib.py index 6ad09bd42d45..2c25a4a18258 100755 --- a/autotest/utilities/test_gdal_grid_lib.py +++ b/autotest/utilities/test_gdal_grid_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -175,6 +159,7 @@ def test_gdal_grid_lib_2(tmp_vsimem, env): # May fail on minimum builds without qhull @gdaltest.disable_exceptions() +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_3(): wkt = "POLYGON ((37.3495241627097 55.6901648563184 187.680953979492,37.349543273449 55.6901565410051 187.714370727539,37.3495794832707 55.6901531392856 187.67333984375,37.3496210575104 55.6901595647556 187.6396484375,37.3496398329735 55.6901716597552 187.596603393555,37.3496726900339 55.6901780852222 187.681350708008,37.3496793955565 55.6901829988139 187.933898925781,37.3496921360493 55.6901860225623 187.934280395508,37.3497162759304 55.6902037870796 187.435394287109,37.3497484624386 55.6902094566047 187.515319824219,37.3497618734837 55.6902241973661 190.329940795898,37.3497511446476 55.690238560154 190.345748901367,37.3497404158115 55.6902567026153 190.439697265625,37.3497142642736 55.6902650179072 189.086044311523,37.349688783288 55.6902608602615 187.763305664062,37.3496626317501 55.6902468754498 187.53678894043,37.3496378213167 55.6902412059301 187.598648071289,37.3496103286743 55.6902400720261 187.806274414062,37.3495902121067 55.6902313787607 187.759521484375,37.3495734483004 55.6902177719067 187.578125,37.349532879889 55.6902035980954 187.56965637207,37.3495161160827 55.6901939599008 187.541793823242,37.3495187982917 55.6901754394418 187.610427856445,37.3495241627097 55.6901648563184 187.680953979492))" @@ -227,6 +212,7 @@ def _shift_by(geom, dx, dy): @pytest.mark.parametrize("alg", ["invdist", "invdistnn"]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_invdistnn_quadrant_all_params(alg): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 100000000)" @@ -253,6 +239,7 @@ def test_gdal_grid_lib_invdistnn_quadrant_all_params(alg): @pytest.mark.parametrize("alg", ["invdist", "invdistnn"]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_invdistnn_quadrant_insufficient_radius(alg): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -272,6 +259,7 @@ def test_gdal_grid_lib_invdistnn_quadrant_insufficient_radius(alg): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_invdistnn_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -291,6 +279,7 @@ def test_gdal_grid_lib_invdistnn_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_invdistnn_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -311,6 +300,7 @@ def test_gdal_grid_lib_invdistnn_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_invdistnn_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 100000000)" @@ -341,6 +331,7 @@ def test_gdal_grid_lib_invdistnn_quadrant_ignore_extra_points(): _compare_arrays(ds, [[10.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 100)" @@ -362,6 +353,7 @@ def test_gdal_grid_lib_average_quadrant_all_params(): _compare_arrays(ds, [[expected_val]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -381,6 +373,7 @@ def test_gdal_grid_lib_average_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -400,6 +393,7 @@ def test_gdal_grid_lib_average_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -420,6 +414,7 @@ def test_gdal_grid_lib_average_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 100000000)" @@ -450,6 +445,7 @@ def test_gdal_grid_lib_average_quadrant_ignore_extra_points(): _compare_arrays(ds, [[10.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_minimum_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 9,1 0 5)" @@ -469,6 +465,7 @@ def test_gdal_grid_lib_minimum_quadrant_all_params(): _compare_arrays(ds, [[5.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_minimum_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -488,6 +485,7 @@ def test_gdal_grid_lib_minimum_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_minimum_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -507,6 +505,7 @@ def test_gdal_grid_lib_minimum_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_minimum_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -527,6 +526,7 @@ def test_gdal_grid_lib_minimum_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_minimum_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 1)" @@ -546,6 +546,7 @@ def test_gdal_grid_lib_minimum_quadrant_ignore_extra_points(): _compare_arrays(ds, [[10.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_maximum_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 11,1 0 50)" @@ -565,6 +566,7 @@ def test_gdal_grid_lib_maximum_quadrant_all_params(): _compare_arrays(ds, [[50.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_maximum_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -584,6 +586,7 @@ def test_gdal_grid_lib_maximum_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_maximum_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10)" @@ -603,6 +606,7 @@ def test_gdal_grid_lib_maximum_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_maximum_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -623,6 +627,7 @@ def test_gdal_grid_lib_maximum_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_maximum_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 10,1 0 100)" @@ -642,6 +647,7 @@ def test_gdal_grid_lib_maximum_quadrant_ignore_extra_points(): _compare_arrays(ds, [[10.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_range_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 50)" @@ -661,6 +667,7 @@ def test_gdal_grid_lib_range_quadrant_all_params(): _compare_arrays(ds, [[50.0 - 1.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_range_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -680,6 +687,7 @@ def test_gdal_grid_lib_range_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_range_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -699,6 +707,7 @@ def test_gdal_grid_lib_range_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_range_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -719,6 +728,7 @@ def test_gdal_grid_lib_range_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_range_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 100)" @@ -738,6 +748,7 @@ def test_gdal_grid_lib_range_quadrant_ignore_extra_points(): _compare_arrays(ds, [[9.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_count_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 50)" @@ -757,6 +768,7 @@ def test_gdal_grid_lib_count_quadrant_all_params(): _compare_arrays(ds, [[5]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_count_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -776,6 +788,7 @@ def test_gdal_grid_lib_count_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_count_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -795,6 +808,7 @@ def test_gdal_grid_lib_count_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_count_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -815,6 +829,7 @@ def test_gdal_grid_lib_count_quadrant_missing_point_in_one_quadrant(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_count_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 100)" @@ -834,6 +849,7 @@ def test_gdal_grid_lib_count_quadrant_ignore_extra_points(): _compare_arrays(ds, [[4.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_distance_quadrant_all_params(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 50)" @@ -855,6 +871,7 @@ def test_gdal_grid_lib_average_distance_quadrant_all_params(): _compare_arrays(ds, [[expected_val]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_distance_quadrant_insufficient_radius(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -874,6 +891,7 @@ def test_gdal_grid_lib_average_distance_quadrant_insufficient_radius(): _compare_arrays(ds, [[0.0]]) # insufficient radius. should be > sqrt(2) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_distance_quadrant_min_points_not_reached(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 0)" @@ -893,6 +911,7 @@ def test_gdal_grid_lib_average_distance_quadrant_min_points_not_reached(): _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_distance_quadrant_missing_point_in_one_quadrant(): # Missing point in 0.5 -0.5 quadrant @@ -913,6 +932,7 @@ def test_gdal_grid_lib_average_distance_quadrant_missing_point_in_one_quadrant() _compare_arrays(ds, [[0.0]]) +@pytest.mark.require_driver("GeoJSON") def test_gdal_grid_lib_average_distance_quadrant_ignore_extra_points(): wkt = "MULTIPOINT(0.5 0.5 10,-0.5 0.5 10,-0.5 -0.5 10,0.5 -0.5 1,1 0 100)" diff --git a/autotest/utilities/test_gdal_rasterize.py b/autotest/utilities/test_gdal_rasterize.py index f6049bd5becb..bb81108e3e4b 100755 --- a/autotest/utilities/test_gdal_rasterize.py +++ b/autotest/utilities/test_gdal_rasterize.py @@ -11,23 +11,7 @@ # Copyright (c) 2010-2013, Even Rouault # Copyright (c) 2008, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys @@ -56,6 +40,7 @@ def gdal_rasterize_path(): # Simple polygon rasterization (adapted from alg/rasterize.py). +@pytest.mark.require_driver("MapInfo File") def test_gdal_rasterize_1(gdal_rasterize_path, tmp_path): output_tif = str(tmp_path / "rast1.tif") diff --git a/autotest/utilities/test_gdal_rasterize_lib.py b/autotest/utilities/test_gdal_rasterize_lib.py index fa8103c7adf2..bc44636d5fc2 100755 --- a/autotest/utilities/test_gdal_rasterize_lib.py +++ b/autotest/utilities/test_gdal_rasterize_lib.py @@ -11,23 +11,7 @@ # Copyright (c) 2015, Even Rouault # Copyright (c) 2008, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -714,12 +698,14 @@ def test_gdal_rasterize_lib_int64_attribute(): noData = -(1 << 63) target_ds = gdal.Rasterize( - "", vector_ds, format="MEM", attribute="val", width=2, height=2, noData=noData + "", vector_ds, format="MEM", attribute="val", width=2, height=3, noData=noData ) assert target_ds is not None + assert target_ds.RasterXSize == 2 + assert target_ds.RasterYSize == 3 assert target_ds.GetRasterBand(1).DataType == gdal.GDT_Int64 assert target_ds.GetRasterBand(1).GetNoDataValue() == noData - assert struct.unpack("Q" * 4, target_ds.ReadRaster())[0] == val + assert struct.unpack("Q", target_ds.ReadRaster(0, 0, 1, 1))[0] == val ############################################################################### @@ -798,6 +784,7 @@ def test_gdal_rasterize_lib_dict_arguments(): # Test doesn't crash without options +@pytest.mark.require_driver("GeoJSON") def test_gdal_rasterize_no_options(tmp_vsimem): """Test doesn't crash without options""" diff --git a/autotest/utilities/test_gdal_translate.py b/autotest/utilities/test_gdal_translate.py index 446839a4055f..6d21dfc75720 100755 --- a/autotest/utilities/test_gdal_translate.py +++ b/autotest/utilities/test_gdal_translate.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -420,6 +404,10 @@ def test_gdal_translate_15(gdal_translate_path, tmp_path): # Test -of VRT which is a special case +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_16(gdal_translate_path, tmp_path): dst_vrt = str(tmp_path / "test16.vrt") @@ -440,6 +428,10 @@ def test_gdal_translate_16(gdal_translate_path, tmp_path): # Test -expand option to VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("GIF") def test_gdal_translate_17(gdal_translate_path, tmp_path): @@ -483,6 +475,10 @@ def test_gdal_translate_17(gdal_translate_path, tmp_path): # Test translation of a VRT made of VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("BMP") def test_gdal_translate_18(gdal_translate_path, tmp_path): @@ -569,6 +565,7 @@ def test_gdal_translate_20(gdal_translate_path, tmp_path): # in that case, they must be copied +@pytest.mark.require_driver("HFA") def test_gdal_translate_21(gdal_translate_path, tmp_path): dst_img = str(tmp_path / "test_gdal_translate_21.img") @@ -591,9 +588,10 @@ def test_gdal_translate_21(gdal_translate_path, tmp_path): ############################################################################### # Test that statistics are copied only when appropriate (#3889) -# in that case, they must *NOT* be copied +# in this case, they must *NOT* be copied +@pytest.mark.require_driver("HFA") def test_gdal_translate_22(gdal_translate_path, tmp_path): dst_img = str(tmp_path / "test_gdal_translate_22.img") @@ -606,13 +604,11 @@ def test_gdal_translate_22(gdal_translate_path, tmp_path): md = ds.GetRasterBand(1).GetMetadata() ds = None - assert ( - "STATISTICS_MINIMUM" not in md - ), "did not expected a STATISTICS_MINIMUM value." + assert "STATISTICS_MINIMUM" not in md, "did not expect a STATISTICS_MINIMUM value." assert ( "STATISTICS_HISTOBINVALUES" not in md - ), "did not expected a STATISTICS_HISTOBINVALUES value." + ), "did not expect a STATISTICS_HISTOBINVALUES value." ############################################################################### @@ -662,6 +658,7 @@ def test_gdal_translate_24(gdal_translate_path, tmp_path): # Test -norat +@pytest.mark.require_driver("HFA") def test_gdal_translate_25(gdal_translate_path, tmp_path): dst_tif = str(tmp_path / "test_gdal_translate_25.tif") @@ -781,6 +778,10 @@ def test_gdal_translate_28(gdal_translate_path, tmp_path): # Test -r +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_29(gdal_translate_path, tmp_path): dst_tif = str(tmp_path / "test_gdal_translate_29.tif") @@ -962,6 +963,10 @@ def test_gdal_translate_33ter(gdal_translate_path, tmp_path): # Test NBITS is preserved +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_34(gdal_translate_path, tmp_path): dst_vrt = str(tmp_path / "test_gdal_translate_34.vrt") @@ -1007,6 +1012,7 @@ def test_gdal_translate_35(gdal_translate_path, tmp_vsimem): # Test RAT is copied from hfa to gtiff - continuous/athematic +@pytest.mark.require_driver("HFA") def test_gdal_translate_36(gdal_translate_path, tmp_path): dst_tif = str(tmp_path / "test_gdal_translate_36.tif") @@ -1032,6 +1038,7 @@ def test_gdal_translate_36(gdal_translate_path, tmp_path): # Test RAT is copied from hfa to gtiff - thematic +@pytest.mark.require_driver("HFA") def test_gdal_translate_37(gdal_translate_path, tmp_path): dst1_tif = str(tmp_path / "test_gdal_translate_37.tif") @@ -1128,3 +1135,19 @@ def test_gdal_translate_scale_and_unscale_incompatible(gdal_translate_path, tmp_ + f" -a_scale 0.0001 -a_offset 0.1 -unscale ../gcore/data/byte.tif {tmp_vsimem}/out.tif" ) assert "-a_scale/-a_offset are not applied by -unscale" in err + + +############################################################################### +# Test that invalid values of -scale are detected + + +def test_gdal_translate_scale_invalid(gdal_translate_path, tmp_path): + + outfile = tmp_path / "out.tif" + + _, err = gdaltest.runexternal_out_and_err( + f"{gdal_translate_path} -scale 0 255 6 -badarg ../gcore/data/byte.tif {outfile}" + ) + + assert "must be numeric" in err + assert not outfile.exists() diff --git a/autotest/utilities/test_gdal_translate_lib.py b/autotest/utilities/test_gdal_translate_lib.py index 26aa3c21a438..6d58bf601e0c 100755 --- a/autotest/utilities/test_gdal_translate_lib.py +++ b/autotest/utilities/test_gdal_translate_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, Faza Mahamood # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -597,6 +581,10 @@ def test_gdal_translate_lib_104(): # Test GCPs propagation in "VRT path" +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_lib_gcp_vrt_path(): src_ds = gdal.Open("../gcore/data/gcps.vrt") @@ -613,6 +601,10 @@ def test_gdal_translate_lib_gcp_vrt_path(): # Test RPC propagation in "VRT path" +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_lib_rcp_vrt_path(): src_ds = gdal.Open("../gcore/data/rpc.vrt") @@ -624,6 +616,10 @@ def test_gdal_translate_lib_rcp_vrt_path(): # Test GeoLocation propagation in "VRT path" +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdal_translate_lib_geolocation_vrt_path(tmp_vsimem): src_ds = gdal.Open("../gcore/data/sstgeo.vrt") @@ -642,7 +638,12 @@ def test_gdal_translate_lib_colorinterp(): src_ds = gdal.Open("../gcore/data/rgbsmall.tif") # Less bands specified than available - ds = gdal.Translate("", src_ds, options="-f MEM -colorinterp blue,gray") + ds = gdal.Translate( + "", + src_ds, + format="MEM", + colorInterpretation=[gdal.GCI_BlueBand, gdal.GCI_GrayIndex], + ) assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_BlueBand assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_GrayIndex assert ds.GetRasterBand(3).GetColorInterpretation() == gdal.GCI_BlueBand @@ -650,7 +651,10 @@ def test_gdal_translate_lib_colorinterp(): # More bands specified than available and a unknown color interpretation with gdal.quiet_errors(): ds = gdal.Translate( - "", src_ds, options="-f MEM -colorinterp alpha,red,undefined,foo" + "", + src_ds, + format="MEM", + colorInterpretation=["alpha", "red", "undefined", "foo"], ) assert ds.GetRasterBand(1).GetColorInterpretation() == gdal.GCI_AlphaBand assert ds.GetRasterBand(2).GetColorInterpretation() == gdal.GCI_RedBand diff --git a/autotest/utilities/test_gdal_viewshed.py b/autotest/utilities/test_gdal_viewshed.py index 725550858839..945ae886727d 100755 --- a/autotest/utilities/test_gdal_viewshed.py +++ b/autotest/utilities/test_gdal_viewshed.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2020, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/utilities/test_gdaladdo.py b/autotest/utilities/test_gdaladdo.py index 29f23085d3a8..b55a16dc61c7 100755 --- a/autotest/utilities/test_gdaladdo.py +++ b/autotest/utilities/test_gdaladdo.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import array @@ -54,6 +38,10 @@ def gdaladdo_path(): # Similar to tiff_ovr_1 +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdaladdo_1(gdaladdo_path, tmp_path): shutil.copy("../gcore/data/mfloat32.vrt", f"{tmp_path}/mfloat32.vrt") @@ -230,6 +218,10 @@ def test_gdaladdo_partial_refresh_from_projwin(gdaladdo_path, tmp_path): # Test --partial-refresh-from-source-timestamp +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdaladdo_partial_refresh_from_source_timestamp(gdaladdo_path, tmp_path): left_tif = str(tmp_path / "left.tif") @@ -284,6 +276,10 @@ def test_gdaladdo_partial_refresh_from_source_timestamp(gdaladdo_path, tmp_path) # Test --partial-refresh-from-source-extent +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdaladdo_partial_refresh_from_source_extent(gdaladdo_path, tmp_path): left_tif = str(tmp_path / "left.tif") @@ -330,6 +326,10 @@ def test_gdaladdo_partial_refresh_from_source_extent(gdaladdo_path, tmp_path): # Test reuse of previous resampling method and overview levels +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.parametrize("read_only", [True, False]) def test_gdaladdo_reuse_previous_resampling_and_levels( gdaladdo_path, tmp_path, read_only @@ -382,8 +382,13 @@ def test_gdaladdo_reuse_previous_resampling_and_levels( @pytest.mark.require_driver("GPKG") +@pytest.mark.require_driver("GTI") def test_gdaladdo_partial_refresh_from_source_timestamp_gti(gdaladdo_path, tmp_path): + gti_drv = gdal.GetDriverByName("GTI") + if gti_drv.GetMetadataItem("IS_PLUGIN"): + pytest.skip("Test skipped because GTI driver as a plugin") + left_tif = str(tmp_path / "left.tif") right_tif = str(tmp_path / "right.tif") diff --git a/autotest/utilities/test_gdalbuildvrt.py b/autotest/utilities/test_gdalbuildvrt.py index 27b7756ee074..42e6b33aed7b 100755 --- a/autotest/utilities/test_gdalbuildvrt.py +++ b/autotest/utilities/test_gdalbuildvrt.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -35,10 +19,16 @@ from osgeo import gdal, osr -pytestmark = pytest.mark.skipif( - test_cli_utilities.get_gdalbuildvrt_path() is None, - reason="gdalbuildvrt not available", -) +pytestmark = [ + pytest.mark.skipif( + test_cli_utilities.get_gdalbuildvrt_path() is None, + reason="gdalbuildvrt not available", + ), + pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", + ), +] @pytest.fixture(scope="module") diff --git a/autotest/utilities/test_gdalbuildvrt_lib.py b/autotest/utilities/test_gdalbuildvrt_lib.py index 74e41222ed6e..1b1b9b0a67d1 100755 --- a/autotest/utilities/test_gdalbuildvrt_lib.py +++ b/autotest/utilities/test_gdalbuildvrt_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2016, 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. +# SPDX-License-Identifier: MIT ############################################################################### import pathlib @@ -97,6 +81,10 @@ def test_gdalbuildvrt_lib_2(): # Test creating overviews +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalbuildvrt_lib_ovr(tmp_vsimem): tmpfilename = tmp_vsimem / "my.vrt" @@ -616,7 +604,7 @@ def test_gdalbuildvrt_lib_bandList_subset_of_bands_from_multiple_band_source(): ############################################################################### def test_gdalbuildvrt_lib_warnings_and_custom_error_handler(): - class GdalErrorHandler(object): + class GdalErrorHandler: def __init__(self): self.got_failure = False self.got_warning = False @@ -668,6 +656,12 @@ def test_gdalbuildvrt_lib_strict_mode(): ############################################################################### + + +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalbuildvrt_lib_te_touching_on_edge(tmp_vsimem): tmp_filename = tmp_vsimem / "test_gdalbuildvrt_lib_te_touching_on_edge.vrt" @@ -794,6 +788,10 @@ def test_gdalbuildvrt_lib_nodataMaxMaskThreshold_rgba(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalbuildvrt_lib_nodataMaxMaskThreshold_rgb_mask(tmp_vsimem): # UInt16, VRTNodata=0 diff --git a/autotest/utilities/test_gdaldem.py b/autotest/utilities/test_gdaldem.py index 8372008cd1b4..1c934c8f272a 100755 --- a/autotest/utilities/test_gdaldem.py +++ b/autotest/utilities/test_gdaldem.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2009-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -381,6 +365,10 @@ def test_gdaldem_color_relief_cpt(gdaldem_path, tmp_path): # Test gdaldem color relief to VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdaldem_color_relief_vrt(gdaldem_path, n43_colorrelief_tif, tmp_path): output_vrt = str(tmp_path / "n43_colorrelief.vrt") @@ -518,6 +506,10 @@ def test_gdaldem_color_relief_nearest_color_entry(gdaldem_path, tmp_path): # Test gdaldem color relief with -nearest_color_entry and -of VRT +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdaldem_color_relief_nearest_color_entry_vrt(gdaldem_path, tmp_path): output_vrt = str(tmp_path / "n43_colorrelief_nearest.vrt") @@ -584,6 +576,10 @@ def test_gdaldem_color_relief_nodata_nan(gdaldem_path, tmp_path): # Test gdaldem color relief with entries with repeated DEM values in the color table (#6422) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("AAIGRID") def test_gdaldem_color_relief_repeated_entry(gdaldem_path, tmp_path): diff --git a/autotest/utilities/test_gdaldem_lib.py b/autotest/utilities/test_gdaldem_lib.py index af3170465c1e..f7254e2280e5 100755 --- a/autotest/utilities/test_gdaldem_lib.py +++ b/autotest/utilities/test_gdaldem_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -526,6 +510,10 @@ def test_gdaldem_lib_color_relief_nodata_value(tmp_vsimem): gdal.Unlink(colorFilename) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.parametrize( "colorSelection", ["nearest_color_entry", "exact_color_entry", "linear_interpolation"], @@ -563,6 +551,10 @@ def test_gdaldem_lib_color_relief_synthetic(tmp_path, colorSelection, format): assert struct.unpack("B" * 4, ds.GetRasterBand(3).ReadRaster()) == (0, 12, 22, 32) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.parametrize( "colorSelection", ["nearest_color_entry", "exact_color_entry", "linear_interpolation"], diff --git a/autotest/utilities/test_gdalenhance.py b/autotest/utilities/test_gdalenhance.py new file mode 100644 index 000000000000..8b4c02a52ac1 --- /dev/null +++ b/autotest/utilities/test_gdalenhance.py @@ -0,0 +1,186 @@ +#!/usr/bin/env pytest +# -*- coding: utf-8 -*- +############################################################################### +# +# Project: GDAL/OGR Test Suite +# Purpose: gdalenhance testing +# Author: Daniel Baston +# +############################################################################### +# Copyright (c) 2024, ISciences LLC +# +# SPDX-License-Identifier: MIT +############################################################################### + +import gdaltest +import pytest +import test_cli_utilities + +from osgeo import gdal + +pytestmark = pytest.mark.skipif( + test_cli_utilities.get_gdalenhance_path() is None, + reason="gdalenhance not available", +) + + +@pytest.fixture() +def gdalenhance_path(): + return test_cli_utilities.get_gdalenhance_path() + + +############################################################################### +# Output a lookup table, then apply it to the image + + +@pytest.mark.parametrize("histogram_dest", ("file", "stdout")) +def test_gdalenhance_output_histogram(gdalenhance_path, histogram_dest, tmp_path): + + lut_fname = tmp_path / "lut.txt" + + cmd = f"{gdalenhance_path} -quiet -equalize ../gcore/data/rgbsmall.tif" + + if histogram_dest == "file": + cmd += f" -config {lut_fname}" + + out, err = gdaltest.runexternal_out_and_err(cmd) + + assert not err + + if histogram_dest == "stdout": + + lines = out.strip().split("\n") + assert len(lines) == 3 + + assert lines[0].startswith("1:Band ") + assert lines[1].startswith("2:Band ") + assert lines[2].startswith("3:Band ") + + with open(lut_fname, "w") as outfile: + for line in lines: + outfile.write(line.strip()) + outfile.write("\n") + + enhanced_fname = tmp_path / "out.tif" + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} -quiet -config {lut_fname} ../gcore/data/rgbsmall.tif {enhanced_fname}" + ) + + assert not err + + assert enhanced_fname.exists() + + +############################################################################### +# Write a new image directly + + +def test_gdalenhance_output_image(gdalenhance_path, tmp_path): + + infile = "../gcore/data/rgbsmall.tif" + outfile = tmp_path / "out.tif" + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} -quiet -equalize -co COMPRESS=DEFLATE {infile} {outfile}" + ) + + assert not err + + with gdal.Open(infile) as src, gdal.Open(outfile) as dst: + assert src.RasterCount == dst.RasterCount + assert src.RasterXSize == dst.RasterXSize + assert src.RasterYSize == dst.RasterYSize + + # check that -co was honored + assert dst.GetMetadata("IMAGE_STRUCTURE")["COMPRESSION"] == "DEFLATE" + + +############################################################################### +# Usage printed with invalid arguments + + +def test_gdalenhance_invalid_usage(gdalenhance_path, tmp_path): + + infile = "../gcore/data/rgbsmall.tif" + outfile = tmp_path / "out.tif" + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} -quiet {infile} {outfile}" + ) + + assert "ret code = 1" in err + assert "Usage" in out + + +############################################################################### +# Malformed LUT + + +def test_gdalenhance_malformed_lut(gdalenhance_path, tmp_path): + + infile = "../gcore/data/rgbsmall.tif" + outfile = tmp_path / "out.tif" + lut_file = tmp_path / "lut.txt" + + with open(lut_file, "w") as lut: + # not enough counts in each line + lut.write( + "1:Band -0.5:ScaleMin 255.5:ScaleMax " + + " ".join(str(x) for x in range(256)) + + "\n" + ) + lut.write( + "2:Band -0.5:ScaleMin 255.5:ScaleMax " + + " ".join(str(x) for x in range(255)) + + "\n" + ) + lut.write( + "3:Band -0.5:ScaleMin 255.5:ScaleMax " + + " ".join(str(x) for x in range(256)) + + "\n" + ) + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} {infile} {outfile} -config {lut_file}" + ) + + assert "Line 2 seems to be corrupt" in err + assert "ret code = 1" in err + + with open(lut_file, "w") as lut: + # not enough lines + lut.write( + "1:Band -0.5:ScaleMin 255.5:ScaleMax " + + " ".join(str(x) for x in range(256)) + + "\n" + ) + lut.write( + "2:Band -0.5:ScaleMin 255.5:ScaleMax " + + " ".join(str(x) for x in range(256)) + + "\n" + ) + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} {infile} {outfile} -config {lut_file}" + ) + + assert "Did not get 3 lines" in err + assert "ret code = 1" in err + + +############################################################################### +# Invalid output type + + +def test_gdalenhance_invalid_output_type(gdalenhance_path, tmp_path): + + infile = "../gcore/data/rgbsmall.tif" + outfile = tmp_path / "out.tif" + + out, err = gdaltest.runexternal_out_and_err( + f"{gdalenhance_path} -equalize -ot Int16 {infile} {outfile}" + ) + + assert "only supports Byte output" in err + assert "ret code = 1" in err diff --git a/autotest/utilities/test_gdalinfo.py b/autotest/utilities/test_gdalinfo.py index c3857c716b0f..744f1bdb34e1 100755 --- a/autotest/utilities/test_gdalinfo.py +++ b/autotest/utilities/test_gdalinfo.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -124,6 +108,7 @@ def test_gdalinfo_5(gdalinfo_path, tmp_path): # Test a dataset with overviews and RAT +@pytest.mark.require_driver("HFA") def test_gdalinfo_6(gdalinfo_path): ret = gdaltest.runexternal(gdalinfo_path + " ../gdrivers/data/hfa/int.img") @@ -135,6 +120,10 @@ def test_gdalinfo_6(gdalinfo_path): # Test a dataset with GCPs +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalinfo_7(gdalinfo_path): ret = gdaltest.runexternal( @@ -343,6 +332,25 @@ def test_gdalinfo_20(gdalinfo_path): assert "GTiff -raster- (rw+vs): GeoTIFF" in ret +############################################################################### +# Test --formats -json + + +@pytest.mark.require_driver("VRT") +def test_gdalinfo_formats_json(gdalinfo_path): + + ret = json.loads( + gdaltest.runexternal(gdalinfo_path + " --formats -json", check_memleak=False) + ) + assert { + "short_name": "VRT", + "long_name": "Virtual Raster", + "scopes": ["raster", "multidimensional_raster"], + "capabilities": ["open", "create", "create_copy", "virtual_io"], + "file_extensions": ["vrt"], + } in ret + + ############################################################################### # Test erroneous use of --format. @@ -537,6 +545,7 @@ def test_gdalinfo_stats(gdalinfo_path, tmp_path): # Test a dataset with overviews and RAT +@pytest.mark.require_driver("HFA") def test_gdalinfo_33(gdalinfo_path): ret = gdaltest.runexternal(gdalinfo_path + " -json ../gdrivers/data/hfa/int.img") @@ -549,6 +558,10 @@ def test_gdalinfo_33(gdalinfo_path): # Test a dataset with GCPs +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalinfo_34(gdalinfo_path): ret = gdaltest.runexternal(gdalinfo_path + " -json ../gcore/data/gcps.vrt") diff --git a/autotest/utilities/test_gdalinfo_lib.py b/autotest/utilities/test_gdalinfo_lib.py index 8c7cfd3ead44..8333b30d1c02 100755 --- a/autotest/utilities/test_gdalinfo_lib.py +++ b/autotest/utilities/test_gdalinfo_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, Faza Mahamood # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### @@ -341,3 +325,14 @@ def test_gdalinfo_lib_nomask(tmp_path): ret = gdal.Info(ds, format="json", showMask=False) assert "mask" not in ret["bands"][0] + + +############################################################################### + + +def test_gdalinfo_lib_json_stac_common_name(): + + ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + ds.GetRasterBand(1).SetColorInterpretation(gdal.GCI_PanBand) + ret = gdal.Info(ds, options="-json") + assert ret["stac"]["eo:bands"][0]["common_name"] == "pan" diff --git a/autotest/utilities/test_gdallocationinfo.py b/autotest/utilities/test_gdallocationinfo.py index 575fa42c1c85..4e75959308a3 100755 --- a/autotest/utilities/test_gdallocationinfo.py +++ b/autotest/utilities/test_gdallocationinfo.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys @@ -122,6 +106,10 @@ def test_gdallocationinfo_4(gdallocationinfo_path): # Test -lifonly +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdallocationinfo_5(gdallocationinfo_path): ret = gdaltest.runexternal( diff --git a/autotest/utilities/test_gdalmanage.py b/autotest/utilities/test_gdalmanage.py index 22ef87c4c40c..dbf4ed454a09 100644 --- a/autotest/utilities/test_gdalmanage.py +++ b/autotest/utilities/test_gdalmanage.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2024, Alessandro Pasotti # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/utilities/test_gdalmdiminfo.py b/autotest/utilities/test_gdalmdiminfo.py index 9977457513c5..65567314d562 100755 --- a/autotest/utilities/test_gdalmdiminfo.py +++ b/autotest/utilities/test_gdalmdiminfo.py @@ -10,23 +10,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest @@ -48,6 +32,10 @@ def gdalmdiminfo_path(): # Simple test +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdiminfo_1(gdalmdiminfo_path): (ret, err) = gdaltest.runexternal_out_and_err(gdalmdiminfo_path + " data/mdim.vrt") @@ -59,6 +47,10 @@ def test_gdalmdiminfo_1(gdalmdiminfo_path): # Test -if option +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdiminfo_if_option(gdalmdiminfo_path): (ret, err) = gdaltest.runexternal_out_and_err( diff --git a/autotest/utilities/test_gdalmdiminfo_lib.py b/autotest/utilities/test_gdalmdiminfo_lib.py index 9518fb01f84e..2a159b72f4c1 100755 --- a/autotest/utilities/test_gdalmdiminfo_lib.py +++ b/autotest/utilities/test_gdalmdiminfo_lib.py @@ -10,23 +10,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import pathlib diff --git a/autotest/utilities/test_gdalmdimtranslate.py b/autotest/utilities/test_gdalmdimtranslate.py index a6cf1cec7529..d6aedd37fbff 100755 --- a/autotest/utilities/test_gdalmdimtranslate.py +++ b/autotest/utilities/test_gdalmdimtranslate.py @@ -10,23 +10,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -50,6 +34,10 @@ def gdalmdimtranslate_path(): # Simple test +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_1(gdalmdimtranslate_path, tmp_path): dst_vrt = str(tmp_path / "out.vrt") @@ -65,6 +53,10 @@ def test_gdalmdimtranslate_1(gdalmdimtranslate_path, tmp_path): # Test -if option +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_if(gdalmdimtranslate_path, tmp_path): dst_vrt = str(tmp_path / "out.vrt") diff --git a/autotest/utilities/test_gdalmdimtranslate_lib.py b/autotest/utilities/test_gdalmdimtranslate_lib.py index 333f3a74e8d7..acd81ff4312a 100755 --- a/autotest/utilities/test_gdalmdimtranslate_lib.py +++ b/autotest/utilities/test_gdalmdimtranslate_lib.py @@ -10,23 +10,7 @@ ############################################################################### # 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -42,6 +26,10 @@ ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_no_arg(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -53,6 +41,10 @@ def test_gdalmdimtranslate_no_arg(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_multidim_to_mem(): out_ds = gdal.MultiDimTranslate("", "data/mdim.vrt", format="MEM") @@ -67,6 +59,10 @@ def test_gdalmdimtranslate_multidim_to_mem(): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_multidim_to_classic(tmp_vsimem): tmpfile = tmp_vsimem / "out.tif" @@ -84,6 +80,10 @@ def test_gdalmdimtranslate_multidim_to_classic(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_multidim_1d_to_classic(tmp_vsimem): tmpfile = tmp_vsimem / "out.tif" @@ -112,6 +112,10 @@ def test_gdalmdimtranslate_classic_to_classic(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_classic_to_multidim(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -171,6 +175,10 @@ def test_gdalmdimtranslate_classic_to_multidim(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_array(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -252,6 +260,10 @@ def test_gdalmdimtranslate_array(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_array_with_transpose_and_view(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -327,6 +339,10 @@ def test_gdalmdimtranslate_array_with_transpose_and_view(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_group(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -392,6 +408,10 @@ def test_gdalmdimtranslate_group(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_two_groups(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -462,6 +482,10 @@ def test_gdalmdimtranslate_two_groups(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_subset(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -717,6 +741,10 @@ def test_gdalmdimtranslate_subset(tmp_vsimem): ############################################################################### +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_scaleaxes(tmp_vsimem): tmpfile = tmp_vsimem / "out.vrt" @@ -791,6 +819,10 @@ def test_gdalmdimtranslate_scaleaxes(tmp_vsimem): ) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalmdimtranslate_dims_with_same_name_different_size(tmp_vsimem): srcfile = tmp_vsimem / "in.vrt" diff --git a/autotest/utilities/test_gdalsrsinfo.py b/autotest/utilities/test_gdalsrsinfo.py index 02e14de5e7ae..fcc82d958368 100755 --- a/autotest/utilities/test_gdalsrsinfo.py +++ b/autotest/utilities/test_gdalsrsinfo.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2011-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys @@ -144,6 +128,7 @@ def test_gdalsrsinfo_6(gdalsrsinfo_path): # Test -o mapinfo option +@pytest.mark.require_driver("MapInfo File") def test_gdalsrsinfo_7(gdalsrsinfo_path): ret = gdaltest.runexternal(gdalsrsinfo_path + " -o mapinfo ../gcore/data/byte.tif") diff --git a/autotest/utilities/test_gdaltindex.py b/autotest/utilities/test_gdaltindex.py index ae29e50a9883..a3eab02708dc 100755 --- a/autotest/utilities/test_gdaltindex.py +++ b/autotest/utilities/test_gdaltindex.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/utilities/test_gdaltindex_lib.py b/autotest/utilities/test_gdaltindex_lib.py index 1ca76128ea5f..505093b0d2f7 100644 --- a/autotest/utilities/test_gdaltindex_lib.py +++ b/autotest/utilities/test_gdaltindex_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2023, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -108,7 +92,7 @@ def test_gdaltindex_lib_basic(four_tile_index): def test_gdaltindex_lib_already_existing_rasters(four_tiles, four_tile_index, tmp_path): - class GdalErrorHandler(object): + class GdalErrorHandler: def __init__(self): self.warnings = [] @@ -163,7 +147,7 @@ def test_gdaltindex_skipDifferentProjection(tmp_path, four_tile_index): ds.SetGeoTransform([47, 0.1, 0, 2, 0, -0.1]) ds = None - class GdalErrorHandler(object): + class GdalErrorHandler: def __init__(self): self.warning = None @@ -234,6 +218,7 @@ def test_gdaltindex_lib_outputSRS_writeAbsoluePath(tmp_path, four_tile_index): # Test -f, -lyr_name +@pytest.mark.require_driver("MapInfo File") def test_gdaltindex_lib_format_layerName(tmp_path, four_tiles): index_mif = str(tmp_path / "test_gdaltindex6.mif") @@ -458,3 +443,19 @@ def test_gdaltindex_lib_fetch_md(tmp_path, four_tiles): lyr = ds.GetLayer(0) f = lyr.GetNextFeature() assert f["foo_field"] == "bar" + + +############################################################################### +# Test -ot + + +@pytest.mark.require_driver("GPKG") +def test_gdaltindex_lib_ot(tmp_path, four_tiles): + + index_filename = str(tmp_path / "test_gdaltindex_lib_ot.gpkg") + + gdal.TileIndex(index_filename, four_tiles[0], options="-ot UInt16") + + ds = ogr.Open(index_filename) + lyr = ds.GetLayer(0) + assert lyr.GetMetadataItem("DATA_TYPE") == "UInt16" diff --git a/autotest/utilities/test_gdaltransform.py b/autotest/utilities/test_gdaltransform.py index 667f12209b9f..34a163b7855e 100755 --- a/autotest/utilities/test_gdaltransform.py +++ b/autotest/utilities/test_gdaltransform.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2009, 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. +# SPDX-License-Identifier: MIT ############################################################################### import sys diff --git a/autotest/utilities/test_gdalwarp.py b/autotest/utilities/test_gdalwarp.py index ee749fed657d..6c499ab8fd66 100755 --- a/autotest/utilities/test_gdalwarp.py +++ b/autotest/utilities/test_gdalwarp.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -383,6 +367,10 @@ def test_gdalwarp_14(gdalwarp_path, testgdalwarp_gcp_tif, tmp_path): # Test -of VRT which is a special case +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalwarp_16(gdalwarp_path, testgdalwarp_gcp_tif, tmp_path): dst_vrt = str(tmp_path / "testgdalwarp16.vrt") @@ -426,12 +414,13 @@ def test_gdalwarp_18(gdalwarp_path, tmp_path): dst_tif = str(tmp_path / "testgdalwarp18.tif") (_, ret_stderr) = gdaltest.runexternal_out_and_err( - f"{gdalwarp_path} -wm 20 -multi ../gcore/data/byte.tif {dst_tif}" + f"{gdalwarp_path} -wm 20MB -multi ../gcore/data/byte.tif {dst_tif}" ) # This error will be returned if GDAL is not compiled with thread support if ret_stderr.find("CPLCreateThread() failed in ChunkAndWarpMulti()") != -1: pytest.skip("GDAL not compiled with thread support") + assert not ret_stderr ds = gdal.Open(dst_tif) assert ds is not None @@ -463,6 +452,10 @@ def test_gdalwarp_19(gdalwarp_path, testgdalwarp_gcp_tif, tmp_path): # Test -of VRT -et 0 which is a special case +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalwarp_20(gdalwarp_path, testgdalwarp_gcp_tif, tmp_path): dst_vrt = str(tmp_path / "testgdalwarp20.vrt") @@ -1047,6 +1040,10 @@ def test_gdalwarp_39(gdalwarp_path, tmp_path): # Test -ovr +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalwarp_40(gdalwarp_path, tmp_path): src_tif = str(tmp_path / "test_gdalwarp_40_src.tif") @@ -1164,6 +1161,25 @@ def test_gdalwarp_40(gdalwarp_path, tmp_path): expected_cs = ds.GetRasterBand(1).Checksum() ds = None + # Test that tiny variations in -te that result in a target resampling factor + # very close to the one of overview 0 lead to overview 0 been selected + + gdaltest.runexternal( + f"{gdalwarp_path} {src_tif} {dst_vrt} -overwrite -ts 10 10 -te 440721 3750120 441920 3751320 -of VRT" + ) + + ds = gdal.Open(dst_vrt) + assert ds.GetRasterBand(1).Checksum() == cs_ov0 + ds = None + + gdaltest.runexternal( + f"{gdalwarp_path} {src_tif} {dst_vrt} -overwrite -ts 10 10 -te 440719 3750120 441920 3751320 -of VRT" + ) + + ds = gdal.Open(dst_vrt) + assert ds.GetRasterBand(1).Checksum() == cs_ov0 + ds = None + # Should select overview 0 too gdaltest.runexternal(f"{gdalwarp_path} {src_tif} {dst_tif} -overwrite -ts 7 7") @@ -1572,3 +1588,22 @@ def test_gdalwarp_if_option(gdalwarp_path, tmp_vsimem): f"{gdalwarp_path} -if HFA ../gcore/data/byte.tif {tmp_vsimem}/out.tif" ) assert err is not None + + +############################################################################### +# Test invalid -wm + + +def test_gdalwarp_invalid_wm(gdalwarp_path, tmp_vsimem): + + ret, err = gdaltest.runexternal_out_and_err( + f"{gdalwarp_path} ../gcore/data/byte.tif {tmp_vsimem}/out.tif -wm maximum" + ) + assert "non-numeric" in err + assert "Failed to parse value of -wm" in err + + ret, err = gdaltest.runexternal_out_and_err( + f"{gdalwarp_path} ../gcore/data/byte.tif {tmp_vsimem}/out.tif -wm 200%" + ) + assert "Memory percentage" in err + assert "Failed to parse value of -wm" in err diff --git a/autotest/utilities/test_gdalwarp_lib.py b/autotest/utilities/test_gdalwarp_lib.py index 3134d0a8d9dd..b3d0363ca362 100755 --- a/autotest/utilities/test_gdalwarp_lib.py +++ b/autotest/utilities/test_gdalwarp_lib.py @@ -11,23 +11,7 @@ # Copyright (c) 2015, Faza Mahamood # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -450,6 +434,19 @@ def test_gdalwarp_lib_19(testgdalwarp_gcp_tif): ds = None +############################################################################### +# Test invalid value of -et + + +def test_gdalwarp_lib_invalid_et(testgdalwarp_gcp_tif): + + with gdaltest.enable_exceptions(): + with pytest.raises(Exception, match="Failed to parse"): + gdal.Warp( + "", "../gcore/data/byte.tif", format="MEM", errorThreshold="minimal" + ) + + ############################################################################### # Test cutline from OGR datasource. @@ -795,6 +792,7 @@ def test_gdalwarp_lib_45(): @pytest.mark.require_driver("CSV") +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_46(tmp_vsimem): ds = gdal.Warp( @@ -891,6 +889,7 @@ def test_gdalwarp_lib_46(tmp_vsimem): # Test -crop_to_cutline -tr X Y -wo CUTLINE_ALL_TOUCHED=YES (fixes for #1360) +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_cutline_all_touched_single_pixel(tmp_vsimem): cutlineDSName = ( @@ -941,6 +940,7 @@ def test_gdalwarp_lib_cutline_all_touched_single_pixel(tmp_vsimem): @pytest.mark.require_driver("CSV") +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_crop_to_cutline_slightly_shifted_wrt_pixel_boundaries(tmp_vsimem): cutlineDSName = ( @@ -1505,6 +1505,7 @@ def test_gdalwarp_lib_dstnodata(dstNodata): # Test automatic densification of cutline (#6375) +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_128(tmp_vsimem): mem_ds = gdal.GetDriverByName("MEM").Create("", 1177, 4719) @@ -1599,7 +1600,12 @@ def test_gdalwarp_lib_128(tmp_vsimem): # to an invalid geometry (#6375) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_geos +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_129(tmp_vsimem): mem_ds = gdal.GetDriverByName("MEM").Create("", 1000, 2000) @@ -1830,7 +1836,10 @@ def test_gdalwarp_lib_134(tmp_vsimem): "", src_ds, format="MEM", - transformerOptions=["SRC_METHOD=NO_GEOTRANSFORM", "DST_METHOD=NO_GEOTRANSFORM"], + transformerOptions={ + "SRC_METHOD": "NO_GEOTRANSFORM", + "DST_METHOD": "NO_GEOTRANSFORM", + }, outputBounds=[1, 2, 4, 6], ) assert ds is not None @@ -2069,6 +2078,10 @@ def test_gdalwarp_lib_135h(gdalwarp_135_grid_gtx, gdalwarp_135_grid2_gtx): assert data == pytest.approx(115 / (1200.0 / 3937)), "Bad value" +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) @pytest.mark.require_driver("GTX") def test_gdalwarp_lib_135i( gdalwarp_135_src_ds, gdalwarp_135_grid_gtx, gdalwarp_135_grid2_gtx, tmp_path @@ -3058,6 +3071,7 @@ def test_gdalwarp_lib_scale_offset(): # Test cutline with zero-width sliver +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_cutline_zero_width_sliver(tmp_vsimem): # Geometry valid in EPSG:4326, but that has a zero-width sliver @@ -3079,6 +3093,7 @@ def test_gdalwarp_lib_cutline_zero_width_sliver(tmp_vsimem): # Test cutline with zero-width sliver +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_cutline_zero_width_sliver_remove_empty_polygon(tmp_vsimem): geojson = { @@ -3120,6 +3135,7 @@ def test_gdalwarp_lib_cutline_zero_width_sliver_remove_empty_polygon(tmp_vsimem) # Test cutline with zero-width sliver +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_cutline_zero_width_sliver_remove_empty_inner_ring(tmp_vsimem): geojson = { @@ -3324,6 +3340,10 @@ def test_gdalwarp_lib_src_nodata_with_dstalpha(): # Test warping from a dataset with points outside of Earth (fixes #4934) +@pytest.mark.skipif( + not gdaltest.vrt_has_open_support(), + reason="VRT driver open missing", +) def test_gdalwarp_lib_src_points_outside_of_earth(): class MyHandler: def __init__(self): @@ -3913,6 +3933,7 @@ def test_gdalwarp_lib_working_data_type_with_source_dataset_of_different_types() @pytest.mark.require_geos +@pytest.mark.require_driver("GeoJSON") def test_gdalwarp_lib_cutline_crossing_antimeridian_in_EPSG_32601_and_raster_in_EPSG_4326( tmp_vsimem, ): @@ -4102,7 +4123,7 @@ def DISABLED_test_gdalwarp_lib_to_projection_without_inverse_method(): def test_gdalwarp_lib_no_crash_on_none_dst(): ds1 = gdal.Open("../gcore/data/byte.tif") - with pytest.raises(ValueError): + with pytest.raises(Exception): gdal.Warp(None, ds1) @@ -4259,3 +4280,143 @@ def test_gdalwarp_lib_minus_180_plus_180_to_span_over_180(tmp_vsimem, extra_colu ) == src_ds.GetRasterBand(1).ReadRaster( 0, 0, src_ds.RasterXSize // 2, src_ds.RasterYSize ) + + +############################################################################### +# Test bugfix for https://lists.osgeo.org/pipermail/gdal-dev/2024-September/059512.html + + +@pytest.mark.parametrize("with_tap", [True, False]) +def test_gdalwarp_lib_blank_edge_one_by_one(with_tap): + + src_ds = gdal.GetDriverByName("MEM").Create("", 1, 1) + src_ds.SetGeoTransform([6.8688, 0.0009, 0, 51.3747, 0, -0.0009]) + srs = osr.SpatialReference() + srs.SetFromUserInput("WGS84") + srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) + src_ds.SetSpatialRef(srs) + options = "-f MEM -tr 1000 1000 -t_srs EPSG:32631" + if with_tap: + options += " -tap" + out_ds = gdal.Warp("", src_ds, options=options) + assert out_ds.RasterXSize == 1 + assert out_ds.RasterYSize == 1 + gt = out_ds.GetGeoTransform() + if with_tap: + assert gt == pytest.approx((769000.0, 1000.0, 0.0, 5699000.0, 0.0, -1000.0)) + else: + assert gt == pytest.approx( + (769234.6506516202, 1000.0, 0.0, 5698603.782217737, 0.0, -1000.0) + ) + + +############################################################################### +# Test bugfix for https://github.com/OSGeo/gdal/issues/10892 + + +def test_gdalwarp_lib_average_ten_ten_to_one_one(): + + src_ds = gdal.GetDriverByName("MEM").Create("", 10, 10) + src_ds.SetGeoTransform([0, 1, 0, 0, 0, -1]) + srs = osr.SpatialReference() + srs.SetFromUserInput("WGS84") + srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) + src_ds.SetSpatialRef(srs) + src_ds.GetRasterBand(1).Fill(1) + out_ds = gdal.Warp( + "", src_ds, width=1, height=1, resampleAlg=gdal.GRIORA_Average, format="MEM" + ) + assert out_ds.GetRasterBand(1).ComputeRasterMinMax() == (1, 1) + + +############################################################################### +# Test bugfix for https://github.com/OSGeo/gdal/issues/10975 + + +def test_gdalwarp_lib_src_is_geog_arc_second(): + + out_ds = gdal.Warp( + "", + "data/geog_arc_second.tif", + options="-f MEM -srcnodata 0 -te -81.5 28.5 -81.0 29.0 -t_srs EPSG:4326", + ) + assert out_ds.RasterXSize == 5464 + assert out_ds.RasterYSize == 5464 + assert out_ds.GetRasterBand(1).Checksum() == 31856 + + +############################################################################### +# Test GWKCubicResampleNoMasks4MultiBandT() + + +def test_gdalwarp_lib_cubic_multiband_byte_4sample_optim(): + + src_ds = gdal.Open("../gdrivers/data/small_world.tif") + + # RGB only + out_ds = gdal.Warp( + "", + src_ds, + options="-f MEM -tr 0.9 0.9 -te -10 40.1 8.9 59 -r cubic", + ) + assert out_ds.RasterXSize == 21 + assert out_ds.RasterYSize == 21 + assert [out_ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 4785, + 4689, + 5007, + ] + + # With dest alpha + out_ds = gdal.Warp( + "", + src_ds, + options="-f MEM -tr 0.9 0.9 -te -10 40.1 8.9 59 -r cubic -dstalpha", + ) + assert out_ds.RasterXSize == 21 + assert out_ds.RasterYSize == 21 + assert [out_ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 4785, + 4689, + 5007, + ] + assert out_ds.GetRasterBand(4).ComputeRasterMinMax() == (255, 255) + + # Test edge effects + # (slightly change the target resolution so that the nearest approximation + # doesn't kick in) + out_ds = gdal.Warp( + "", + src_ds, + options="-f MEM -r cubic -tr 0.9000001 0.9000001 -wo XSCALE=1 -wo YSCALE=1", + ) + assert out_ds.RasterXSize == 400 + assert out_ds.RasterYSize == 200 + assert out_ds.ReadRaster() == src_ds.ReadRaster() + + +############################################################################### +# Test GWKCubicResampleNoMasks4MultiBandT() + + +def test_gdalwarp_lib_cubic_multiband_uint16_4sample_optim(): + + src_ds = gdal.Open("../gdrivers/data/small_world.tif") + src_ds = gdal.Translate( + "", src_ds, options="-f MEM -ot UInt16 -scale 0 255 0 65535" + ) + + # RGB only + out_ds = gdal.Warp( + "", + src_ds, + options="-f MEM -tr 0.9 0.9 -te -10 40.1 8.9 59 -r cubic", + ) + out_ds = gdal.Translate("", out_ds, options="-f MEM -ot Byte -scale 0 65535 0 255") + assert out_ds.RasterXSize == 21 + assert out_ds.RasterYSize == 21 + assert [out_ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 4785, + 4689, + 5007, + ] diff --git a/autotest/utilities/test_gnmutils.py b/autotest/utilities/test_gnmutils.py index 77a70a6f649c..e8e27a6eec84 100755 --- a/autotest/utilities/test_gnmutils.py +++ b/autotest/utilities/test_gnmutils.py @@ -12,23 +12,7 @@ # Copyright (c) 2014, Mikhail Gusev # Copyright (c) 2014-2015, NextGIS # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import os diff --git a/autotest/utilities/test_nearblack.py b/autotest/utilities/test_nearblack.py index ca99c3d2b2ef..0b44ad3ae37b 100755 --- a/autotest/utilities/test_nearblack.py +++ b/autotest/utilities/test_nearblack.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2010-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import shutil diff --git a/autotest/utilities/test_nearblack_lib.py b/autotest/utilities/test_nearblack_lib.py index 22cae1d68bee..8d23b24da7b3 100755 --- a/autotest/utilities/test_nearblack_lib.py +++ b/autotest/utilities/test_nearblack_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, 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. +# SPDX-License-Identifier: MIT ############################################################################### diff --git a/autotest/utilities/test_ogr2ogr.py b/autotest/utilities/test_ogr2ogr.py index bc218fb45855..791fddcf0b00 100755 --- a/autotest/utilities/test_ogr2ogr.py +++ b/autotest/utilities/test_ogr2ogr.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -306,12 +290,21 @@ def test_ogr2ogr_13(ogr2ogr_path, tmp_path): def test_ogr2ogr_14(ogr2ogr_path, tmp_path): - output_shp = str(tmp_path / "poly.shp") + output_shp = tmp_path / "poly.shp" - gdaltest.runexternal( + # invalid value + _, err = gdaltest.runexternal_out_and_err( + ogr2ogr_path + f" -segmentize small_bits {output_shp} ../ogr/data/poly.shp poly" + ) + assert "Failed to parse" in err + assert not output_shp.exists() + + _, err = gdaltest.runexternal_out_and_err( ogr2ogr_path + f" -segmentize 100 {output_shp} ../ogr/data/poly.shp poly" ) + assert not err + ds = ogr.Open(output_shp) assert ds is not None and ds.GetLayer(0).GetFeatureCount() == 10 feat = ds.GetLayer(0).GetNextFeature() @@ -716,6 +709,42 @@ def test_ogr2ogr_27(ogr2ogr_path, tmp_path): ), "unexpected extent" +############################################################################### +# Test -clipdst with clip from bounding box + + +@pytest.mark.require_geos +def test_ogr2ogr_clipdst_bbox(ogr2ogr_path, tmp_path): + + output_shp = tmp_path / "poly.shp" + + xmin = 479400 + xmax = 480300 + ymin = 4764500 + ymax = 4765100 + + _, err = gdaltest.runexternal_out_and_err( + f"{ogr2ogr_path} {output_shp} ../ogr/data/poly.shp -clipdst {xmin}x {ymin} {xmax} {ymax}" + ) + + assert "cannot load dest clip geometry" in err + assert not output_shp.exists() + + _, err = gdaltest.runexternal_out_and_err( + f"{ogr2ogr_path} {output_shp} ../ogr/data/poly.shp -clipdst {xmin} {ymin} {xmax} {ymax}" + ) + + ds = ogr.Open(output_shp) + assert ds is not None and ds.GetLayer(0).GetFeatureCount() == 7 + + assert ds.GetLayer(0).GetExtent() == ( + xmin, + xmax, + ymin, + ymax, + ), "unexpected extent" + + ############################################################################### # Test -wrapdateline on linestrings @@ -1419,7 +1448,7 @@ def test_ogr2ogr_49_bis(ogr2ogr_path, tmp_path): """""", """""", """grid""", - """ """, + """ """, """ 440750.000""", """ """, """""", @@ -2082,6 +2111,7 @@ def ogr2ogr_62_json(tmp_path): return fname +@pytest.mark.require_driver("GeoJSON") def test_ogr2ogr_62(ogr2ogr_path, ogr2ogr_62_json, tmp_path): dst_json = str(tmp_path / "test_ogr2ogr_62.json") @@ -2097,6 +2127,7 @@ def test_ogr2ogr_62(ogr2ogr_path, ogr2ogr_62_json, tmp_path): assert "bar" in data and "baz" in data +@pytest.mark.require_driver("GeoJSON") def test_ogr2ogr_62bis(ogr2ogr_path, ogr2ogr_62_json, tmp_path): dst_json = str(tmp_path / "test_ogr2ogr_62bis.json") diff --git a/autotest/utilities/test_ogr2ogr_lib.py b/autotest/utilities/test_ogr2ogr_lib.py index dbfec4cba68f..2526163097a2 100755 --- a/autotest/utilities/test_ogr2ogr_lib.py +++ b/autotest/utilities/test_ogr2ogr_lib.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2015, Faza Mahamood # -# 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. +# SPDX-License-Identifier: MIT ############################################################################### import collections @@ -1649,6 +1633,13 @@ def test_ogr2ogr_lib_simplify(): f.SetGeometry(ogr.CreateGeometryFromWkt("LINESTRING(0 0, 1 0, 10 0)")) src_lyr.CreateFeature(f) + with gdaltest.enable_exceptions(), pytest.raises( + Exception, match="Failed to parse" + ): + gdal.VectorTranslate( + "", src_ds, format="Memory", simplifyTolerance="reasonable" + ) + dst_ds = gdal.VectorTranslate("", src_ds, format="Memory", simplifyTolerance=5) dst_lyr = dst_ds.GetLayer(0) @@ -2182,6 +2173,7 @@ def test_ogr2ogr_lib_reprojection_curve_geometries_forced_geom_type(geometryType @pytest.mark.require_driver("CSV") +@pytest.mark.require_driver("GeoJSON") def test_ogr2ogr_lib_reprojection_curve_geometries_output_does_not_support_curve( tmp_vsimem, ): @@ -2829,3 +2821,140 @@ def test_ogr2ogr_lib_skip_invalid(tmp_vsimem): lyr = ds.GetLayer(0) assert lyr.GetFeatureCount() == 1 ds = None + + +############################################################################### +# Test -t_srs in Arrow code path + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize("force_reproj_threading", [False, True]) +@pytest.mark.parametrize("source_driver", ["GPKG", "Parquet"]) +def test_ogr2ogr_lib_reproject_arrow(tmp_vsimem, source_driver, force_reproj_threading): + + src_driver = gdal.GetDriverByName(source_driver) + if src_driver is None: + pytest.skip(f"{source_driver} is not available") + src_filename = str(tmp_vsimem / ("in." + source_driver.lower())) + with src_driver.Create(src_filename, 0, 0, 0, gdal.GDT_Unknown) as srcDS: + srs = osr.SpatialReference() + srs.ImportFromEPSG(32631) + srcLayer = srcDS.CreateLayer("test", srs=srs) + f = ogr.Feature(srcLayer.GetLayerDefn()) + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT(500000 4500000)")) + srcLayer.CreateFeature(f) + f = ogr.Feature(srcLayer.GetLayerDefn()) + srcLayer.CreateFeature(f) + f = ogr.Feature(srcLayer.GetLayerDefn()) + f.SetGeometry(ogr.CreateGeometryFromWkt("POINT(500000 4000000)")) + srcLayer.CreateFeature(f) + + config_options = {"CPL_DEBUG": "ON", "OGR2OGR_USE_ARROW_API": "YES"} + if force_reproj_threading: + config_options["OGR2OGR_MIN_FEATURES_FOR_THREADED_REPROJ"] = "0" + + with gdal.OpenEx(src_filename) as src_ds: + for i in range(2): + + got_msg = [] + + def my_handler(errorClass, errno, msg): + got_msg.append(msg) + return + + with gdaltest.error_handler(my_handler), gdaltest.config_options( + config_options + ): + ds = gdal.VectorTranslate( + "", src_ds, format="Memory", dstSRS="EPSG:4326" + ) + + assert "OGR2OGR: Using WriteArrowBatch()" in got_msg + + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 3 + f = lyr.GetNextFeature() + ogrtest.check_feature_geometry(f, "POINT(3 40.65085651557158)") + f = lyr.GetNextFeature() + assert f.GetGeometryRef() is None + f = lyr.GetNextFeature() + ogrtest.check_feature_geometry(f, "POINT(3 36.14471809881776)") + + +############################################################################### +# Test -t_srs in Arrow code path in a situation where it cannot be triggered +# currently (source CRS is crossing anti-meridian) + + +@gdaltest.enable_exceptions() +@pytest.mark.require_geos +@pytest.mark.require_driver("GPKG") +def test_ogr2ogr_lib_reproject_arrow_optim_cannot_trigger(tmp_vsimem): + + src_filename = str(tmp_vsimem / "in.gpkg") + with gdal.GetDriverByName("GPKG").Create( + src_filename, 0, 0, 0, gdal.GDT_Unknown + ) as srcDS: + srs = osr.SpatialReference() + srs.ImportFromEPSG(32660) + srcLayer = srcDS.CreateLayer("test", srs=srs) + f = ogr.Feature(srcLayer.GetLayerDefn()) + f.SetGeometry( + ogr.CreateGeometryFromWkt( + "LINESTRING(657630.64 4984896.17,815261.43 4990738.26)" + ) + ) + srcLayer.CreateFeature(f) + + got_msg = [] + + def my_handler(errorClass, errno, msg): + got_msg.append(msg) + return + + config_options = {"CPL_DEBUG": "ON", "OGR2OGR_USE_ARROW_API": "YES"} + with gdaltest.error_handler(my_handler), gdaltest.config_options(config_options): + ds = gdal.VectorTranslate("", src_filename, format="Memory", dstSRS="EPSG:4326") + + assert "OGR2OGR: Using WriteArrowBatch()" not in got_msg + + lyr = ds.GetLayer(0) + assert lyr.GetFeatureCount() == 1 + f = lyr.GetNextFeature() + assert f.GetGeometryRef().GetGeometryType() == ogr.wkbMultiLineString + assert f.GetGeometryRef().GetGeometryCount() == 2 + + +############################################################################### +# Test -explodecollections on empty geometries + + +@gdaltest.enable_exceptions() +@pytest.mark.parametrize( + "input_wkt,expected_output_wkt", + [ + ("MULTIPOINT EMPTY", "POINT EMPTY"), + ("MULTIPOINT Z EMPTY", "POINT Z EMPTY"), + ("MULTIPOINT M EMPTY", "POINT M EMPTY"), + ("MULTIPOINT ZM EMPTY", "POINT ZM EMPTY"), + ("MULTILINESTRING EMPTY", "LINESTRING EMPTY"), + ("MULTIPOLYGON EMPTY", "POLYGON EMPTY"), + ("MULTICURVE EMPTY", "COMPOUNDCURVE EMPTY"), + ("MULTISURFACE EMPTY", "CURVEPOLYGON EMPTY"), + ("GEOMETRYCOLLECTION EMPTY", "GEOMETRYCOLLECTION EMPTY"), + ], +) +def test_ogr2ogr_lib_explodecollections_empty_geoms(input_wkt, expected_output_wkt): + + with gdal.GetDriverByName("Memory").Create("", 0, 0, 0, gdal.GDT_Unknown) as src_ds: + src_lyr = src_ds.CreateLayer("test") + f = ogr.Feature(src_lyr.GetLayerDefn()) + f.SetGeometryDirectly(ogr.CreateGeometryFromWkt(input_wkt)) + src_lyr.CreateFeature(f) + + out_ds = gdal.VectorTranslate( + "", src_ds, explodeCollections=True, format="Memory" + ) + out_lyr = out_ds.GetLayer(0) + f = out_lyr.GetNextFeature() + assert f.GetGeometryRef().ExportToIsoWkt() == expected_output_wkt diff --git a/autotest/utilities/test_ogrinfo.py b/autotest/utilities/test_ogrinfo.py index 1d15129dd13e..25fcda0584a3 100755 --- a/autotest/utilities/test_ogrinfo.py +++ b/autotest/utilities/test_ogrinfo.py @@ -10,25 +10,10 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### +import json import os import pathlib import stat @@ -324,6 +309,25 @@ def test_ogrinfo_19(ogrinfo_path): assert "ESRI Shapefile -vector- (rw+v): ESRI Shapefile" in ret +############################################################################### +# Test --formats -json + + +@pytest.mark.require_driver("ESRI Shapefile") +def test_ogrinfo_formats_json(ogrinfo_path): + + ret = json.loads( + gdaltest.runexternal(ogrinfo_path + " --formats -json", check_memleak=False) + ) + assert { + "short_name": "ESRI Shapefile", + "long_name": "ESRI Shapefile", + "scopes": ["vector"], + "capabilities": ["open", "create", "virtual_io"], + "file_extensions": ["shp", "dbf", "shz", "shp.zip"], + } in ret + + ############################################################################### # Test --help-general @@ -521,6 +525,7 @@ def test_ogrinfo_23(ogrinfo_path, tmp_path): # Test metadata +@pytest.mark.require_driver("OGR_VRT") def test_ogrinfo_24(ogrinfo_path, tmp_path): vrt_fname = str(tmp_path / "test_ogrinfo_24.vrt") diff --git a/autotest/utilities/test_ogrinfo_lib.py b/autotest/utilities/test_ogrinfo_lib.py index 876f75e935ff..1f9b58631639 100755 --- a/autotest/utilities/test_ogrinfo_lib.py +++ b/autotest/utilities/test_ogrinfo_lib.py @@ -8,23 +8,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import json @@ -317,6 +301,7 @@ def test_ogrinfo_lib_json_relationships(): # Test json output with OFSTJSON field +@pytest.mark.require_driver("GeoJSON") def test_ogrinfo_lib_json_OFSTJSON(): ds = gdal.OpenEx( @@ -375,6 +360,7 @@ def test_ogrinfo_lib_json_OFSTJSON(): # Test json output with -fields=NO +@pytest.mark.require_driver("GeoJSON") def test_ogrinfo_lib_json_fields_NO(): ds = gdal.OpenEx( @@ -398,6 +384,7 @@ def test_ogrinfo_lib_json_fields_NO(): # Test json output with -geom=NO +@pytest.mark.require_driver("GeoJSON") def test_ogrinfo_lib_json_geom_NO(): ds = gdal.OpenEx( diff --git a/autotest/utilities/test_ogrlineref.py b/autotest/utilities/test_ogrlineref.py index 2ed5eeee0a24..2eb3a83b7843 100755 --- a/autotest/utilities/test_ogrlineref.py +++ b/autotest/utilities/test_ogrlineref.py @@ -9,23 +9,7 @@ ############################################################################### # Copyright (c) 2008-2014, 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. +# SPDX-License-Identifier: MIT ############################################################################### import os @@ -123,6 +107,7 @@ def test_ogrlineref_4(ogrlineref_path, parts_shp, tmp_path): # test kml +@pytest.mark.require_driver("KML") def test_ogrlineref_5(ogrlineref_path, tmp_path): parts_kml = str(tmp_path / "parts.kml") diff --git a/autotest/utilities/test_ogrtindex.py b/autotest/utilities/test_ogrtindex.py index cd05515a09f3..4c35a9d4d184 100755 --- a/autotest/utilities/test_ogrtindex.py +++ b/autotest/utilities/test_ogrtindex.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2008-2013, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/autotest/utilities/test_sozip.py b/autotest/utilities/test_sozip.py index dc4f08b433d7..c94b18457903 100755 --- a/autotest/utilities/test_sozip.py +++ b/autotest/utilities/test_sozip.py @@ -10,23 +10,7 @@ ############################################################################### # Copyright (c) 2022, 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. +# SPDX-License-Identifier: MIT ############################################################################### import gdaltest diff --git a/ci/travis/conda/libgdal-adbc.patch b/ci/travis/conda/libgdal-adbc.patch new file mode 100644 index 000000000000..53ae85f1e53b --- /dev/null +++ b/ci/travis/conda/libgdal-adbc.patch @@ -0,0 +1,81 @@ +diff --git a/recipe/build.sh b/recipe/build.sh +index ddc8ae6..0e6c07e 100644 +--- a/recipe/build.sh ++++ b/recipe/build.sh +@@ -52,6 +52,7 @@ cmake -G "Unix Makefiles" \ + -DGDAL_ENABLE_DRIVER_HDF5=OFF \ + -DGDAL_ENABLE_DRIVER_AVIF=OFF \ + -DGDAL_ENABLE_DRIVER_HEIF=OFF \ ++ -DOGR_ENABLE_DRIVER_ADBC=OFF \ + -DOGR_REGISTER_DRIVER_ARROW_FOR_LATER_PLUGIN=ON \ + -DOGR_REGISTER_DRIVER_PARQUET_FOR_LATER_PLUGIN=ON \ + -DGDAL_REGISTER_DRIVER_JP2OPENJPEG_FOR_LATER_PLUGIN=ON \ +@@ -68,6 +69,7 @@ cmake -G "Unix Makefiles" \ + -DGDAL_REGISTER_DRIVER_HDF5_FOR_LATER_PLUGIN=ON \ + -DGDAL_REGISTER_DRIVER_AVIF_FOR_LATER_PLUGIN=ON \ + -DGDAL_REGISTER_DRIVER_HEIF_FOR_LATER_PLUGIN=ON \ ++ -DOGR_REGISTER_DRIVER_ADBC_FOR_LATER_PLUGIN=ON \ + -DOGR_DRIVER_ARROW_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-arrow-parquet'" \ + -DOGR_DRIVER_PARQUET_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-arrow-parquet'" \ + -DGDAL_DRIVER_JP2OPENJPEG_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-jp2openjpeg'" \ +@@ -85,6 +87,7 @@ cmake -G "Unix Makefiles" \ + -DGDAL_ENABLE_HDF5_GLOBAL_LOCK:BOOL=ON \ + -DGDAL_DRIVER_AVIF_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-avif'" \ + -DGDAL_DRIVER_HEIF_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-heif'" \ ++ -DOGR_DRIVER_ADBC_PLUGIN_INSTALLATION_MESSAGE="You may install it with 'conda install -c conda-forge libgdal-adbc'" \ + -DBUILD_PYTHON_BINDINGS:BOOL=OFF \ + -DBUILD_JAVA_BINDINGS:BOOL=OFF \ + -DBUILD_CSHARP_BINDINGS:BOOL=OFF \ +diff --git a/recipe/meta.yaml b/recipe/meta.yaml +index e2b6865..28dab04 100644 +--- a/recipe/meta.yaml ++++ b/recipe/meta.yaml +@@ -625,6 +625,48 @@ outputs: + license: MIT + license_file: LICENSE.TXT + ++ - name: libgdal-adbc ++ script: build_plugin.sh # [unix] ++ script: build_plugin.bat # [win] ++ build: ++ # FIXME: libadbc-driver-manager is not available currently on Windows ++ skip: true # [win] ++ ignore_run_exports_from: ++ - expat ++ - icu ++ script_env: ++ - GDAL_PLUGIN_NAME=ADBC ++ - GDAL_PLUGIN_TYPE=ogr ++ - GDAL_PLUGIN_DEPS=-DGDAL_USE_ADBCDRIVERMANAGER=ON ++ requirements: ++ build: ++ - cmake ++ - {{ compiler('c') }} ++ - {{ stdlib("c") }} ++ - {{ compiler('cxx') }} ++ - pkg-config # [not win] ++ - make # [unix] ++ - ninja # [win] ++ host: ++ - {{ pin_subpackage('libgdal-core', exact=True) }} ++ # GH992 attempt to workaround dep solver picking wrong libxml2 ++ - icu # [not win] ++ - libkml-devel ++ - expat ++ - libadbc-driver-manager ++ run: ++ - libgdal-core >={{ ".".join(version.split(".")[:2]) }} ++ test: ++ commands: ++ - test -f ${PREFIX}/lib/gdalplugins/${GDAL_PLUGIN_TYPE}_${GDAL_PLUGIN_NAME}${SHLIB_EXT} # [unix] ++ - if not exist %LIBRARY_LIB%\gdalplugins\%GDAL_PLUGIN_TYPE%_%GDAL_PLUGIN_NAME%.dll exit 1 # [win] ++ - ogrinfo --format ${GDAL_PLUGIN_NAME} # [unix] ++ - ogrinfo --format %GDAL_PLUGIN_NAME% # [win] ++ about: ++ summary: Vector driver ADBC for the Geospatial Data Abstraction Library (GDAL) ++ license: MIT ++ license_file: LICENSE.TXT ++ + - name: libgdal + build: + run_exports: diff --git a/ci/travis/conda/setup.sh b/ci/travis/conda/setup.sh index 15dcff7011f5..eb08b2531a5c 100755 --- a/ci/travis/conda/setup.sh +++ b/ci/travis/conda/setup.sh @@ -19,6 +19,8 @@ git clone https://github.com/conda-forge/gdal-feedstock.git cd gdal-feedstock +patch -p1 < ../ci/travis/conda/libgdal-adbc.patch + cat > recipe/recipe_clobber.yaml < /dev/null && echo "yes") || (echo "Missing" && /bin/false) + NPROC=$(sysctl -n hw.ncpu) echo "NPROC=${NPROC}" make -j${NPROC} diff --git a/ci/travis/osx/script.sh b/ci/travis/osx/script.sh index a28b9eeac6be..7b212dfc9deb 100755 --- a/ci/travis/osx/script.sh +++ b/ci/travis/osx/script.sh @@ -7,6 +7,9 @@ export PROJ_NETWORK=ON echo 'Running CPP unit tests' (cd build && make quicktest) +echo 'Running CPP perftests' +(cd build && ctest -V -R perf) + echo 'Running Python unit tests' # install test dependencies sudo -H pip3 install -r autotest/requirements.txt diff --git a/cmake/helpers/CheckDependentLibraries.cmake b/cmake/helpers/CheckDependentLibraries.cmake index 0ca740ea69e0..ca5d76ef1909 100644 --- a/cmake/helpers/CheckDependentLibraries.cmake +++ b/cmake/helpers/CheckDependentLibraries.cmake @@ -147,7 +147,7 @@ set_package_properties( URL "https://libtiff.gitlab.io/libtiff/" DESCRIPTION "Support for the Tag Image File Format (TIFF)." TYPE RECOMMENDED) -gdal_internal_library(TIFF REQUIRED) +gdal_internal_library(TIFF) if (DEFINED ENV{CONDA_PREFIX} AND UNIX) # Currently on Unix, the Zstd cmake config file is buggy. It declares a @@ -449,6 +449,22 @@ gdal_check_package(MONGOCXX "Enable MongoDBV3 driver" CAN_DISABLE) define_find_package2(HEIF libheif/heif.h heif PKGCONFIG_NAME libheif) gdal_check_package(HEIF "HEIF >= 1.1" CAN_DISABLE) +include(CheckCXXSourceCompiles) +check_cxx_source_compiles( + " + #include + int main() + { + struct heif_image_tiling tiling; + return 0; + } + " + LIBHEIF_SUPPORTS_TILES +) +if (LIBHEIF_SUPPORTS_TILES) + set_property(TARGET HEIF::HEIF APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "LIBHEIF_SUPPORTS_TILES") +endif () + include(CheckDependentLibrariesAVIF) include(CheckDependentLibrariesOpenJPEG) @@ -473,12 +489,13 @@ option(GDAL_USE_PUBLICDECOMPWT # proprietary libraries KAKADU include(CheckDependentLibrariesKakadu) -gdal_check_package(LURATECH "Enable JP2Lura driver" CAN_DISABLE) include(CheckDependentLibrariesArrowParquet) gdal_check_package(OpenDrive "Enable libOpenDRIVE" CONFIG CAN_DISABLE) +gdal_check_package(AdbcDriverManager "Enable ADBC" CONFIG CAN_DISABLE) + # bindings # finding python in top of project because of common for autotest and bindings diff --git a/cmake/helpers/CheckDependentLibrariesGeoTIFF.cmake b/cmake/helpers/CheckDependentLibrariesGeoTIFF.cmake index 82ea7cbc70fe..a2ab32b933fe 100644 --- a/cmake/helpers/CheckDependentLibrariesGeoTIFF.cmake +++ b/cmake/helpers/CheckDependentLibrariesGeoTIFF.cmake @@ -2,4 +2,4 @@ gdal_check_package(GeoTIFF "libgeotiff library (external)" CAN_DISABLE RECOMMEND NAMES GeoTIFF TARGETS geotiff_library GEOTIFF::GEOTIFF ) -gdal_internal_library(GEOTIFF REQUIRED) +gdal_internal_library(GEOTIFF) diff --git a/cmake/helpers/GdalCompilationFlags.cmake b/cmake/helpers/GdalCompilationFlags.cmake index 3501de613802..f25e3c72550c 100644 --- a/cmake/helpers/GdalCompilationFlags.cmake +++ b/cmake/helpers/GdalCompilationFlags.cmake @@ -118,6 +118,8 @@ else () detect_and_set_cxx_warning_flag(non-virtual-dtor) detect_and_set_cxx_warning_flag(overloaded-virtual) detect_and_set_cxx_warning_flag(suggest-override) + # clang specific only. Avoids that foo("bar") goes to foo(bool) instead of foo(const std::string&) + detect_and_set_cxx_warning_flag(string-conversion) check_cxx_compiler_flag(-fno-operator-names HAVE_FLAG_NO_OPERATOR_NAMES) if (HAVE_FLAG_NO_OPERATOR_NAMES) @@ -159,7 +161,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_CXX_COMPILER_ID STREQUAL check_cxx_compiler_flag(-fno-finite-math-only HAVE_FLAG_NO_FINITE_MATH_ONLY) if (HAVE_FLAG_NO_FINITE_MATH_ONLY) # Intel CXX compiler based on clang defaults to -ffinite-math-only, which breaks std::isinf(), std::isnan(), etc. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-finite-math-only") + add_compile_options("-fno-finite-math-only") endif () set(TEST_LINK_STDCPP_SOURCE_CODE diff --git a/cmake/helpers/GdalDriverHelper.cmake b/cmake/helpers/GdalDriverHelper.cmake index ad07cb3d407c..23be3dd9aa22 100644 --- a/cmake/helpers/GdalDriverHelper.cmake +++ b/cmake/helpers/GdalDriverHelper.cmake @@ -559,9 +559,16 @@ macro(ogr_default_driver name desc) add_feature_info(ogr_${key} OGR_ENABLE_DRIVER_${key} "${desc}") add_subdirectory(${name}) endmacro() -macro(ogr_default_driver2 name key desc) - set(OGR_ENABLE_DRIVER_${key} ON CACHE BOOL "${desc}" FORCE) - add_feature_info(ogr_${key} OGR_ENABLE_DRIVER_${key} "${desc}") - add_subdirectory(${name}) -endmacro() +function(add_driver_embedded_resources driver_target is_plugin_var c_filename) + add_library(${driver_target}_resources OBJECT ${c_filename}) + gdal_standard_includes(${driver_target}_resources) + set_property(TARGET ${driver_target}_resources PROPERTY POSITION_INDEPENDENT_CODE ${GDAL_OBJECT_LIBRARIES_POSITION_INDEPENDENT_CODE}) + target_compile_definitions(${driver_target} PRIVATE EMBED_RESOURCE_FILES) + set_target_properties(${driver_target}_resources PROPERTIES C_STANDARD 23) + if (${${is_plugin_var}}) + target_sources(${driver_target} PRIVATE $) + else() + target_sources(${GDAL_LIB_TARGET_NAME} PRIVATE $) + endif() +endfunction() diff --git a/cmake/helpers/GdalVersion.cmake b/cmake/helpers/GdalVersion.cmake index 7961085ba325..ca8a35926093 100644 --- a/cmake/helpers/GdalVersion.cmake +++ b/cmake/helpers/GdalVersion.cmake @@ -48,6 +48,40 @@ endif () if (EXISTS ${GDAL_ROOT_SOURCE_DIR}/.git) set(GDAL_DEV_SUFFIX "dev") + + # Try look in the Git tags to see if it is a special version + find_package(Git QUIET) + if(GIT_FOUND) + execute_process( + COMMAND "${GIT_EXECUTABLE}" "tag" "--points-at" "HEAD" + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE git_result + OUTPUT_VARIABLE git_tags + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(git_result EQUAL 0) + # First replaces the line breaks by a ";", so we can iterate over it + string(REGEX REPLACE "\r?\n" ";" git_tags "${git_tags}") + foreach(git_tag ${git_tags}) + # GDAL is currently not fully compatible with Semantic Versioning 2.0.0, as there would have to be a minus before the pre-release tag, so we allow it to be omitted. + if (git_tag MATCHES "^v${GDAL_VERSION_MAJOR}.${GDAL_VERSION_MINOR}.${GDAL_VERSION_REV}-?(.*)") + # ${CMAKE_MATCH_1} contains the pre-release suffix + if (NOT CMAKE_MATCH_1) + # In case there is no pre-release suffix, it is a release version. + set(GDAL_DEV_SUFFIX "") + # Ignore further suffixes (e.g., a RC tag) + break() + else() + # Take the pre-release suffix as dev suffix. Normally there should only be one pre-release tag, + # so we don't need any logic here to compare the pre-release tags with each other. However, + # as there may still be a release tag without a pre-release suffix, we do not break the loop. + set(GDAL_DEV_SUFFIX "${CMAKE_MATCH_1}") + endif() + endif() + endforeach() + endif() + endif() else() set(GDAL_DEV_SUFFIX "") endif() diff --git a/cmake/modules/packages/FindDB2.cmake b/cmake/modules/packages/FindDB2.cmake deleted file mode 100644 index 2fd2324b4a6e..000000000000 --- a/cmake/modules/packages/FindDB2.cmake +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# CMake module to search for DB2 client library -# -# On success, the macro sets the following variables: -# DB2_FOUND = if the library found -# DB2_LIBRARY = full path to the library -# DB2_LIBRARIES = full path to the library -# DB2_INCLUDE_DIR = where to find the library headers -# -# Copyright (c) 2013 Denis Chapligin -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# -############################################################################### - -if(UNIX) - set(DB2_INSTALL_PATHS - /opt/ibm/db2/V10.1 - /opt/ibm/db2/V9.7 - /opt/ibm/db2/V9.5 - /opt/ibm/db2/V9.1 - /opt/ibm/clidriver - /opt/clidriver) - - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(DB2_LIBDIRS "lib32" "lib") - else() - set(DB2_LIBDIRS "lib64" "lib") - endif() - - set(DB2_FIND_INCLUDE_PATHS) - set(DB2_FIND_LIB_PATHS) - foreach(db2_install_path ${DB2_INSTALL_PATHS}) - if (IS_DIRECTORY ${db2_install_path}/include) - set(DB2_FIND_INCLUDE_PATHS - ${DB2_FIND_INCLUDE_PATHS} - ${db2_install_path}/include) - endif() - foreach(db2_libdir ${DB2_LIBDIRS}) - if (IS_DIRECTORY ${db2_install_path}/${db2_libdir}) - set(DB2_FIND_LIB_PATHS - ${DB2_FIND_LIB_PATHS} - ${db2_install_path}/${db2_libdir}) - endif() - endforeach(db2_libdir) - endforeach(db2_install_path) -elseif(WIN32) - if (CMAKE_CL_64) # 64-bit build, DB2 64-bit installed - set(DB2_FIND_INCLUDE_PATHS $ENV{ProgramW6432}/IBM/SQLLIB/include) - set(DB2_FIND_LIB_PATHS $ENV{ProgramW6432}/IBM/SQLLIB/lib) - else() # 32-bit build, DB2 64-bit or DB2 32-bit installed - - if(EXISTS "$ENV{ProgramW6432}/IBM/SQLLIB/lib") - # On 64-bit Windows with DB2 64-bit installed: - # LIB environment points to {DB2}/IBM/SQLLIB/lib with64-bit db2api.lib, - # this flag prevents checking paths in LIB, so Win32 version can be detected - set(DB2_FIND_LIB_NO_LIB NO_SYSTEM_ENVIRONMENT_PATH) - - endif() - - set(DB2_FIND_INCLUDE_PATHS - $ENV{ProgramW6432}/IBM/SQLLIB/include - $ENV{ProgramFiles}/IBM/SQLLIB/include) - set(DB2_FIND_LIB_PATHS - $ENV{ProgramFiles}/IBM/SQLLIB/lib - $ENV{ProgramFiles}/IBM/SQLLIB/lib/win32 - $ENV{ProgramW6432}/IBM/SQLLIB/lib/win32) - endif() -endif() - -find_path(DB2_INCLUDE_DIR sqlcli1.h - $ENV{DB2_INCLUDE_DIR} - $ENV{DB2_DIR}/include - $ENV{DB2_HOME} - $ENV{IBM_DB_INCLUDE} - ${DB2_FIND_INCLUDE_PATHS}) - -find_library(DB2_LIBRARY - NAMES db2 db2api - PATHS - $ENV{DB2LIB} - $ENV{IBM_DB_LIB} - ${DB2_FIND_LIB_PATHS} - ${DB2_FIND_LIB_NO_LIB}) - -if(DB2_LIBRARY) - get_filename_component(DB2_LIBRARY_DIR ${DB2_LIBRARY} PATH) -endif() - -if(DB2_INCLUDE_DIR AND DB2_LIBRARY_DIR) - set(DB2_FOUND TRUE) -endif() - -set(DB2_LIBRARIES ${DB2_LIBRARY}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(DB2 - DEFAULT_MSG - DB2_INCLUDE_DIR - DB2_LIBRARIES) - -mark_as_advanced(DB2_INCLUDE_DIR DB2_LIBRARIES) diff --git a/cmake/modules/packages/FindLURATECH.cmake b/cmake/modules/packages/FindLURATECH.cmake deleted file mode 100644 index b5874c66888a..000000000000 --- a/cmake/modules/packages/FindLURATECH.cmake +++ /dev/null @@ -1,35 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file COPYING-CMAKE-SCRIPTS or https://cmake.org/licensing for details. - -# - Try to find the LURATECH library -# -# Once done this will define -# -# LURATECH_FOUND - System has Luratech -# LURATECH_INCLUDE_DIR - The Luratech include directory -# LURATECH_LIBRARIES - The libraries needed to use Luratech - -find_path(LURATECH_INCLUDE_DIR lwf_jp2.h HINTS ${LURATECH_ROOT}/include) - -find_library(LURATECH_LIBRARY NAMES _lwf_jp2 lwf_jp2 PATH_SUFFIXES library HINTS ${LURATECH_ROOT}/library) - -mark_as_advanced(LURATECH_INCLUDE_DIR LURATECH_LIBRARY) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LURATECH - FOUND_VAR LURATECH_FOUND - REQUIRED_VARS LURATECH_LIBRARY LURATECH_INCLUDE_DIR - VERSION_VAR LURATECH_VERSION_STRING -) - -if(LURATECH_FOUND) - set(LURATECH_LIBRARIES "${LURATECH_LIBRARY}") - set(LURATECH_INCLUDE_DIRS "${LURATECH_INCLUDE_DIR}") - if(NOT TARGET LURATECH::LURATECH) - add_library(LURATECH::LURATECH UNKNOWN IMPORTED) - set_target_properties(LURATECH::LURATECH PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${LURATECH_INCLUDE_DIRS}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${LURATECH_LIBRARIES}") - endif() -endif() diff --git a/cmake/modules/thirdparty/FindDotnet.cmake b/cmake/modules/thirdparty/FindDotnet.cmake index 945688b6eb47..499634228d63 100644 --- a/cmake/modules/thirdparty/FindDotnet.cmake +++ b/cmake/modules/thirdparty/FindDotnet.cmake @@ -5,24 +5,24 @@ # # FindDotnet # ---------- -# +# # Find DotNet executable, and initialize functions for adding dotnet projects. -# +# # Results are reported in the following variables:: -# +# # DOTNET_FOUND - True if dotnet executable is found # DOTNET_EXE - Dotnet executable # DOTNET_VERSION - Dotnet version as reported by dotnet executable # DOTNET_SDKS - Dotnet SDKs loaded as reported by dotnet executable # NUGET_EXE - Nuget executable (WIN32 only) # NUGET_CACHE_PATH - Nuget package cache path -# +# # The following functions are defined to add dotnet/msbuild projects: -# +# # ADD_DOTNET -- add a project to be built by dotnet. -# +# # ``` -# ADD_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] +# ADD_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] # [CONFIG configuration] # [PLATFORM platform] # [PACKAGE nuget_package_dependencies... ] @@ -34,12 +34,12 @@ # [ARGUMENTS additional_build_args...] # [PACK_ARGUMENTS additional_pack_args...]) # ``` -# -# RUN_DOTNET -- Run a project with `dotnet run`. The `OUTPUT` argument represents artifacts +# +# RUN_DOTNET -- Run a project with `dotnet run`. The `OUTPUT` argument represents artifacts # produced by running the .NET program, and can be consumed from other build steps. -# +# # ``` -# RUN_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] +# RUN_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] # [ARGUMENTS program_args...] # [OUTPUT outputs...] # [CONFIG configuration] @@ -49,11 +49,11 @@ # [CUSTOM_BUILDPROPS value....] # [SOURCES additional_file_dependencies... ]) # ``` -# +# # ADD_MSBUILD -- add a project to be built by msbuild. Windows-only. When building in Unix systems, msbuild targets are skipped. -# +# # ``` -# ADD_MSBUILD( [RELEASE|DEBUG] [X86|X64|ANYCPU] +# ADD_MSBUILD( [RELEASE|DEBUG] [X86|X64|ANYCPU] # [CONFIG configuration] # [PLATFORM platform] # [PACKAGE output_nuget_packages... ] @@ -68,7 +68,7 @@ # and if the program fails to build or run, the build fails. Currently only .NET Core App framework is supported. # Multiple smoke tests will be run one-by-one to avoid global resource conflicts. # -# SMOKETEST_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] +# SMOKETEST_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU] # [ARGUMENTS program_args...] # [CONFIG configuration] # [PLATFORM platform] @@ -76,12 +76,12 @@ # [OUTPUT_PATH output_path relative to cmake binary output dir] # [CUSTOM_BUILDPROPS value....] # [SOURCES additional_file_dependencies... ]) -# +# # For all the above functions, `RELEASE|DEBUG` overrides `CONFIG`, `X86|X64|ANYCPU` overrides PLATFORM. # # # DOTNET_REGISTER_LOCAL_REPOSITORY -- register a local NuGet package repository. -# +# # ``` # DOTNET_REGISTER_LOCAL_REPOSITORY(repo_name repo_path) # ``` @@ -97,7 +97,7 @@ # [ARGUMENTS additional_dotnet_test_args...] # [OUTPUT_PATH output_path relative to cmake binary output dir]) # ``` -# +# # GEN_DOTNET_PROPS -- Generates a Directory.Build.props file. The created file is populated with MSBuild properties: # - DOTNET_PACKAGE_VERSION: a version string that can be referenced in the actual project file as $(DOTNET_PACKAGE_VERSION). # The version string value can be set with PACKAGE_VERSION argument, and defaults to '1.0.0'. @@ -111,10 +111,7 @@ # [PACKAGE_VERSION version] # [XML_INJECT xml_injection]) # ``` -# -# Require 3.5 for batch copy multiple files - -cmake_minimum_required(VERSION 3.5.0) +# IF(DOTNET_FOUND) RETURN() @@ -184,11 +181,11 @@ ENDFUNCTION() FUNCTION(DOTNET_GET_DEPS _DN_PROJECT arguments) CMAKE_PARSE_ARGUMENTS( # prefix - _DN + _DN # options (flags) - "RELEASE;DEBUG;X86;X64;ANYCPU;NETCOREAPP" + "RELEASE;DEBUG;X86;X64;ANYCPU;NETCOREAPP" # oneValueArgs - "NAME;CONFIG;PLATFORM;VERSION;OUTPUT_PATH" + "NAME;CONFIG;PLATFORM;VERSION;OUTPUT_PATH" # multiValueArgs "PACKAGE;DEPENDS;ARGUMENTS;PACK_ARGUMENTS;OUTPUT;SOURCES;CUSTOM_BUILDPROPS,BUILD_OPTIONS" # the input arguments @@ -199,7 +196,7 @@ FUNCTION(DOTNET_GET_DEPS _DN_PROJECT arguments) GET_FILENAME_COMPONENT(_DN_projname "${_DN_PROJECT}" NAME) STRING(REGEX REPLACE "\\.[^.]*$" "" _DN_projname_noext ${_DN_projname}) - FILE(GLOB_RECURSE DOTNET_deps + FILE(GLOB_RECURSE DOTNET_deps ${_DN_proj_dir}/*.cs ${_DN_proj_dir}/*.fs ${_DN_proj_dir}/*.vb @@ -328,14 +325,14 @@ ENDMACRO() MACRO(DOTNET_BUILD_COMMANDS) IF(${DOTNET_IS_MSBUILD}) - SET(build_dotnet_cmds + SET(build_dotnet_cmds COMMAND ${CMAKE_COMMAND} -E echo "======= Building msbuild project ${DOTNET_PROJNAME} [${DOTNET_CONFIG} ${DOTNET_PLATFORM}]" COMMAND ${NUGET_EXE} restore -Force ${DOTNET_PROJPATH} COMMAND ${DOTNET_EXE} msbuild ${DOTNET_PROJPATH} /t:Clean ${DOTNET_BUILD_PROPERTIES} /p:Configuration="${DOTNET_CONFIG}" COMMAND ${DOTNET_EXE} msbuild ${DOTNET_PROJPATH} /t:Build ${DOTNET_BUILD_PROPERTIES} /p:Configuration="${DOTNET_CONFIG}" ${DOTNET_ARGUMENTS}) SET(build_dotnet_type "msbuild") ELSE() - SET(build_dotnet_cmds + SET(build_dotnet_cmds COMMAND ${CMAKE_COMMAND} -E echo "======= Building .NET project ${DOTNET_PROJNAME} [${DOTNET_CONFIG} ${DOTNET_PLATFORM}]") foreach (_src ${DOTNET_SOURCES} ) LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} add ${DOTNET_PROJPATH} reference ${_src}) @@ -362,10 +359,10 @@ MACRO(DOTNET_BUILD_COMMANDS) MESSAGE("-- Adding ${build_dotnet_type} project ${DOTNET_PROJPATH} (no nupkg)") ENDIF() endif() - - LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} pack - --no-build --no-restore ${DOTNET_PROJPATH} - -c ${DOTNET_CONFIG} ${DOTNET_BUILD_PROPERTIES} ${DOTNET_PACK_OPTIONS} + + LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} pack + --no-build --no-restore ${DOTNET_PROJPATH} + -c ${DOTNET_CONFIG} ${DOTNET_BUILD_PROPERTIES} ${DOTNET_PACK_OPTIONS} --output ${CMAKE_CURRENT_BINARY_DIR} -p:PackageVersion=${DOTNET_PACKAGE_VERSION} ) LIST(APPEND DOTNET_OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.buildtimestamp) LIST(APPEND build_dotnet_cmds COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.buildtimestamp) @@ -416,7 +413,7 @@ FUNCTION(RUN_DOTNET DOTNET_PROJECT) COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp WORKING_DIRECTORY ${DOTNET_OUTPUT_PATH}) ADD_CUSTOM_TARGET( - ${DOTNET_PROJNAME} + ${DOTNET_PROJNAME} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp ${DOTNET_RUN_OUTPUT}) ADD_DOTNET_DEPENDENCY_TARGETS() ENDFUNCTION() @@ -469,9 +466,9 @@ FUNCTION(GEN_DOTNET_PROPS target_props_file) # prefix _DNP # options (flags) - "" + "" # oneValueArgs - "PACKAGE_VERSION;XML_INJECT" + "PACKAGE_VERSION;XML_INJECT" # multiValueArgs "" # the input arguments @@ -496,4 +493,4 @@ ENDFUNCTION() MESSAGE("-- Found .NET toolchain: ${DOTNET_EXE} (version ${DOTNET_VERSION})") -SET(DOTNET_FOUND TRUE) \ No newline at end of file +SET(DOTNET_FOUND TRUE) diff --git a/doc/build/html_extra/robots.txt b/doc/build/html_extra/robots.txt deleted file mode 100644 index 1b0f0fd8b207..000000000000 --- a/doc/build/html_extra/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * -Allow: /en/latest/ -Disallow: /en/ diff --git a/doc/generate-sponsor-logos.sh b/doc/generate-sponsor-logos.sh index 5c50b73897d9..5488febe19ea 100755 --- a/doc/generate-sponsor-logos.sh +++ b/doc/generate-sponsor-logos.sh @@ -19,3 +19,4 @@ inkscape --export-png=images/sponsors/logo-koordinates.png --export-width=$BRONZ inkscape --export-png=images/sponsors/logo-frontiersi.png --export-width=$BRONZE_WIDTH images/sponsors/logo-FrontierSI.svg inkscape --export-png=images/sponsors/logo-aerometrex.png --export-width=$BRONZE_WIDTH images/sponsors/logo-aerometrex.svg inkscape --export-png=images/sponsors/logo-geoczech.png --export-width=$BRONZE_WIDTH images/sponsors/logo-geoczech.svg +inkscape --export-png=images/sponsors/logo-linz.png --export-width=$BRONZE_WIDTH images/sponsors/logo-linz.svg diff --git a/doc/images/programs/gdalenhance_little_spruce.jpg b/doc/images/programs/gdalenhance_little_spruce.jpg new file mode 100644 index 000000000000..5815f7d3956e Binary files /dev/null and b/doc/images/programs/gdalenhance_little_spruce.jpg differ diff --git a/doc/images/programs/gdalenhance_little_spruce_enhanced.jpg b/doc/images/programs/gdalenhance_little_spruce_enhanced.jpg new file mode 100644 index 000000000000..3804af6ac38b Binary files /dev/null and b/doc/images/programs/gdalenhance_little_spruce_enhanced.jpg differ diff --git a/doc/images/sponsors/logo-linz.png b/doc/images/sponsors/logo-linz.png new file mode 100644 index 000000000000..a1fae96f54b1 Binary files /dev/null and b/doc/images/sponsors/logo-linz.png differ diff --git a/doc/images/sponsors/logo-linz.svg b/doc/images/sponsors/logo-linz.svg new file mode 100644 index 000000000000..587ff230db6f --- /dev/null +++ b/doc/images/sponsors/logo-linz.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/old_trac_pointers.md b/doc/old_trac_pointers.md new file mode 100644 index 000000000000..b40174b7562b --- /dev/null +++ b/doc/old_trac_pointers.md @@ -0,0 +1,8 @@ +Google Summer of Code ideas: https://web.archive.org/web/20240812224510/https://trac.osgeo.org/gdal/wiki/SummerOfCode +Google Summer of Code selected projects: https://web.archive.org/web/20240812232901/https://trac.osgeo.org/gdal/wiki/SoCProjects +Old Sponsorship program: http://web.archive.org/web/20230921154549/https://trac.osgeo.org/gdal/wiki/Sponsorship +Old Build hints: http://web.archive.org/https://trac.osgeo.org/gdal/wiki/BuildHints +Additional notes on utilities: http://web.archive.org/https://trac.osgeo.org/gdal/wiki/UserDocs +CodeSnippets: http://web.archive.org/https://trac.osgeo.org/gdal/wiki/CodeSnippets +LayerAlgebra: http://web.archive.org/https://trac.osgeo.org/gdal/wiki/LayerAlgebra +Old FAQ: http://web.archive.org/https://trac.osgeo.org/gdal/wiki/FAQ diff --git a/doc/requirements.txt b/doc/requirements.txt index e4378d870530..da22d12e3326 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,12 +1,16 @@ # This file may be used to create an environment using: # $ pip install --upgrade -r +breathe +fsspec numpy sphinx -breathe sphinx_bootstrap_theme -sphinxcontrib-bibtex -sphinx_rtd_theme -recommonmark sphinx-markdown-tables -sphinxcontrib-spelling +sphinx_rtd_theme +sphinxcontrib-bibtex sphinxcontrib-jquery +# We use a slightly forked version +# sphinxcontrib-programoutput +sphinxcontrib-spelling +myst_nb +recommonmark diff --git a/doc/rtd/pre_build.sh b/doc/rtd/pre_build.sh index 56d8d8060346..3faeba2ffb56 100755 --- a/doc/rtd/pre_build.sh +++ b/doc/rtd/pre_build.sh @@ -13,7 +13,7 @@ cmake \ -DGDAL_PYTHON_INSTALL_PREFIX=${PREFIX} \ -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \ -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \ - -DBUILD_APPS=OFF \ + -DBUILD_APPS=ON \ -DBUILD_PYTHON_BINDINGS=ON \ -DBUILD_JAVA_BINDINGS=ON \ -DBUILD_TESTING=OFF \ diff --git a/doc/source/_extensions/cli_example.py b/doc/source/_extensions/cli_example.py new file mode 100644 index 000000000000..dcd097d50a1a --- /dev/null +++ b/doc/source/_extensions/cli_example.py @@ -0,0 +1,125 @@ +from docutils import nodes +from sphinx.addnodes import pending_xref +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective, SphinxRole + + +class ExampleRole(SphinxRole): + def run(self): + return [ + pending_xref( + "", + nodes.Text("placeholder"), + reftype="example", + refdomain="std", + reftarget=self.text, + refdoc=self.env.docname, + ) + ], [] + + +class ExampleDirective(SphinxDirective): + + required_arguments = 0 + has_content = True + + option_spec = { + "title": str, + "id": str, + } + + def run(self): + docname = self.env.docname + + if not hasattr(self.env, "gdal_examples"): + self.env.gdal_examples = {} + + if docname not in self.env.gdal_examples: + self.env.gdal_examples[docname] = {} + + examples = self.env.gdal_examples[docname] + + example_num = len(examples) + 1 + + title_content = self.options.get("title", None) + if title_content: + title_content = f"Example {example_num}: {title_content}" + else: + title_content = f"Example {example_num}" + + id = self.options.get("id", f"{docname}-{example_num}") + examples[id] = example_num + + retnodes = [] + section = nodes.section(ids=[id]) + section.document = self.state.document + + title = nodes.title() + title += self.parse_inline(title_content)[0] + section.append(title) + self.state.nested_parse(self.content, self.content_offset, section) + + retnodes.append(section) + + return retnodes + + +def link_example_refs(app, env, node, contnode): + if node["reftype"] != "example": + return + + example_name = node["reftarget"] + + if hasattr(env, "gdal_examples"): + examples = env.gdal_examples.get(node["refdoc"], {}) + else: + examples = {} + + example_num = examples.get(example_name, None) + + if not example_num: + logger = logging.getLogger(__name__) + + logger.warning( + f"Can't find example {example_name}", + location=node, + ) + + return contnode + + ref_node = nodes.reference("", "", refid=node["reftarget"], internal=True) + ref_node.append(nodes.Text(f'Example {examples.get(node["reftarget"])}')) + + return ref_node + + +def purge_example_defs(app, env, docname): + if not hasattr(env, "gdal_examples"): + return + + if docname in env.gdal_examples: + del env.gdal_examples[docname] + + +def merge_example_defs(app, env, docnames, other): + if not hasattr(env, "gdal_examples"): + env.gdal_examples = {} + + if hasattr(other, "gdal_examples"): + env.gdal_examples.update(other.gdal_examples) + + +def setup(app): + app.add_directive("example", ExampleDirective) + app.add_role("example", ExampleRole()) + + app.connect("env-purge-doc", purge_example_defs) + app.connect("env-merge-info", merge_example_defs) + + app.connect("missing-reference", link_example_refs) + + return { + "version": "0.1", + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/doc/source/_extensions/configoptions.py b/doc/source/_extensions/configoptions.py index a1864376226a..9b6684904d15 100644 --- a/doc/source/_extensions/configoptions.py +++ b/doc/source/_extensions/configoptions.py @@ -133,7 +133,7 @@ def render(self, app): logger = logging.getLogger(__name__) logger.warning( f"Option {self.option_name} :since: should be a sequence of integers and periods (got {self.since_ver})", - location=self.env.docname, + location=app.env.docname, ) if caveats: diff --git a/doc/source/_extensions/sphinxcontrib_programoutput_gdal.py b/doc/source/_extensions/sphinxcontrib_programoutput_gdal.py new file mode 100644 index 000000000000..66db1be0a7d3 --- /dev/null +++ b/doc/source/_extensions/sphinxcontrib_programoutput_gdal.py @@ -0,0 +1,347 @@ +# Slightly customized version with a new 'language' option, submitted as +# https://github.com/OpenNTI/sphinxcontrib-programoutput/pull/62 + +# -*- coding: utf-8 -*- +# Copyright (c) 2010, 2011, 2012, Sebastian Wiesner +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" + sphinxcontrib.programoutput + =========================== + + This extension provides a directive to include the output of commands as + literal block while building the docs. + + .. moduleauthor:: Sebastian Wiesner +""" + +from __future__ import print_function, division, absolute_import + +import sys +import os +import shlex +from subprocess import Popen, PIPE, STDOUT +from collections import defaultdict, namedtuple + +from docutils import nodes +from docutils.parsers import rst +from docutils.parsers.rst.directives import flag, unchanged, nonnegative_int +from docutils.statemachine import StringList + +from sphinx.util import logging as sphinx_logging + +__version__ = '0.18.dev0' + +logger = sphinx_logging.getLogger('contrib.programoutput') + +class program_output(nodes.Element): + pass + + +def _container_wrapper(directive, literal_node, caption): + container_node = nodes.container('', literal_block=True, + classes=['literal-block-wrapper']) + parsed = nodes.Element() + directive.state.nested_parse(StringList([caption], source=''), + directive.content_offset, parsed) + if isinstance(parsed[0], nodes.system_message): # pragma: no cover + # TODO: Figure out if this is really possible and how to produce + # it in a test case. + msg = 'Invalid caption: %s' % parsed[0].astext() + raise ValueError(msg) + assert isinstance(parsed[0], nodes.Element) + caption_node = nodes.caption(parsed[0].rawsource, '', + *parsed[0].children) + caption_node.source = literal_node.source + caption_node.line = literal_node.line + container_node += caption_node + container_node += literal_node + return container_node + + +def _slice(value): + parts = [int(v.strip()) for v in value.split(',')] + if len(parts) > 2: + raise ValueError('too many slice parts') + return tuple((parts + [None] * 2)[:2]) + + +class ProgramOutputDirective(rst.Directive): + has_content = False + final_argument_whitespace = True + required_arguments = 1 + + option_spec = dict(shell=flag, prompt=flag, nostderr=flag, + ellipsis=_slice, extraargs=unchanged, + returncode=nonnegative_int, cwd=unchanged, + caption=unchanged, name=unchanged, + language=unchanged) + + def run(self): + env = self.state.document.settings.env + + node = program_output() + node.line = self.lineno + node['command'] = self.arguments[0] + + if self.name == 'command-output': + node['show_prompt'] = True + else: + node['show_prompt'] = 'prompt' in self.options + + node['hide_standard_error'] = 'nostderr' in self.options + node['extraargs'] = self.options.get('extraargs', '') + _, cwd = env.relfn2path(self.options.get('cwd', '/')) + node['working_directory'] = cwd + node['use_shell'] = 'shell' in self.options + node['returncode'] = self.options.get('returncode', 0) + node['language'] = self.options.get('language', 'text') + if 'ellipsis' in self.options: + node['strip_lines'] = self.options['ellipsis'] + if 'caption' in self.options: + caption = self.options['caption'] or self.arguments[0] + node = _container_wrapper(self, node, caption) + + self.add_name(node) + return [node] + + +_Command = namedtuple( + 'Command', 'command shell hide_standard_error working_directory') + + +class Command(_Command): + """ + A command to be executed. + """ + + def __new__(cls, command, shell=False, hide_standard_error=False, + working_directory='/'): + # `chdir()` resolves symlinks, so we need to resolve them too for + # caching to make sure that different symlinks to the same directory + # don't result in different cache keys. Also normalize paths to make + # sure that identical paths are also equal as strings. + working_directory = os.path.normpath(os.path.realpath( + working_directory)) + # Likewise, normalize the command now for better caching, and so + # that we can present *exactly* what we run to the user. + command = cls.__normalize_command(command, shell) + return _Command.__new__(cls, command, shell, hide_standard_error, + working_directory) + + @staticmethod + def __normalize_command(command, shell): # pylint:disable=unused-private-member + # Returns either a native string, to a tuple. + if (bytes is str + and not isinstance(command, str) + and hasattr(command, 'encode')): + # Python 2, given a unicode string + command = command.encode(sys.getfilesystemencoding()) + assert isinstance(command, str) + + if not shell and isinstance(command, str): + command = shlex.split(command) + + if isinstance(command, list): + command = tuple(command) + + assert isinstance(command, (str, tuple)), command + + return command + + @classmethod + def from_program_output_node(cls, node): + """ + Create a command from a :class:`program_output` node. + """ + extraargs = node.get('extraargs', '') + command = (node['command'] + ' ' + extraargs).strip() + return cls(command, node['use_shell'], + node['hide_standard_error'], node['working_directory']) + + def execute(self): + """ + Execute this command. + + Return the :class:`~subprocess.Popen` object representing the running + command. + """ + command = self.command + + # Popen is a context manager only in Python 3, and we'd have to restructure + # the code to work with it anyway. + # pylint:disable=consider-using-with + return Popen(command, shell=self.shell, stdout=PIPE, + stderr=PIPE if self.hide_standard_error else STDOUT, + cwd=self.working_directory) + + def get_output(self): + """ + Get the output of this command. + + Return a tuple ``(returncode, output)``. ``returncode`` is the + integral return code of the process, ``output`` is the output as + unicode string, with final trailing spaces and new lines stripped. + """ + process = self.execute() + output = process.communicate()[0].decode( + sys.getfilesystemencoding(), 'replace').rstrip() + return process.returncode, output + + def __str__(self): + command = self.command + command = list(command) if isinstance(command, tuple) else command + return repr(command) + + +class ProgramOutputCache(defaultdict): + """ + Execute command and cache their output. + + This class is a mapping. Its keys are :class:`Command` objects represeting + command invocations. Its values are tuples of the form ``(returncode, + output)``, where ``returncode`` is the integral return code of the command, + and ``output`` is the output as unicode string. + + The first time, a key is retrieved from this object, the command is + invoked, and its result is cached. Subsequent access to the same key + returns the cached value. + """ + + def __missing__(self, command): + """ + Called, if a command was not found in the cache. + + ``command`` is an instance of :class:`Command`. + """ + result = command.get_output() + self[command] = result + return result + + +def _prompt_template_as_unicode(app): + tmpl = app.config.programoutput_prompt_template + if isinstance(tmpl, bytes): + for enc in 'utf-8', sys.getfilesystemencoding(): + try: + tmpl = tmpl.decode(enc) + except UnicodeError: # pragma: no cover + pass + else: + app.config.programoutput_prompt_template = tmpl + break + return tmpl + + +def run_programs(app, doctree): + """ + Execute all programs represented by ``program_output`` nodes in + ``doctree``. Each ``program_output`` node in ``doctree`` is then + replaced with a node, that represents the output of this program. + + The program output is retrieved from the cache in + ``app.env.programoutput_cache``. + """ + # The node_class used to be switchable to `sphinxcontrib.ansi.ansi_literal_block` + # if `app.config.programoutput_use_ansi` was set. But sphinxcontrib.ansi + # is no longer available on PyPI, so we can't test that. And if we can't test it, + # we can't support it. + node_class = nodes.literal_block + + cache = app.env.programoutput_cache + + for node in doctree.traverse(program_output): + command = Command.from_program_output_node(node) + try: + returncode, output = cache[command] + except EnvironmentError as error: + error_message = 'Command {0} failed: {1}'.format(command, error) + error_node = doctree.reporter.error(error_message, base_node=node) + # Sphinx 1.8.0b1 started dropping all system_message nodes with a + # level less than 5 by default (or 2 if `keep_warnings` is set to true). + # This appears to be undocumented. Reporting failures is an important + # part of what this extension does, so we raise the default level. + error_node['level'] = 6 + node.replace_self(error_node) + else: + if returncode != node['returncode']: + logger.warning( + 'Unexpected return code %s from command %r (output=%r)', + returncode, command, output + ) + + # replace lines with ..., if ellipsis is specified + + # Recall that `output` is guaranteed to be a unicode string on + # all versions of Python. + if 'strip_lines' in node: + start, stop = node['strip_lines'] + lines = output.splitlines() + lines[start:stop] = [u'...'] + output = u'\n'.join(lines) + + if node['show_prompt']: + # The command in the node is also guaranteed to be + # unicode, but the prompt template might not be. This + # could be a native string on Python 2, or one with an + # explicit b prefix on 2 or 3 (for some reason). + # Attempt to decode it using UTF-8, preferentially, or + # fallback to sys.getfilesystemencoding(). If all that fails, fall back + # to the default encoding (which may have often worked before). + prompt_template = _prompt_template_as_unicode(app) + output = prompt_template.format( + command=node['command'], + output=output, + returncode=returncode + ) + + new_node = node_class(output, output) + new_node['language'] = node['language'] + node.replace_self(new_node) + + + +def init_cache(app): + """ + Initialize the cache for program output at + ``app.env.programoutput_cache``, if not already present (e.g. being + loaded from a pickled environment). + + The cache is of type :class:`ProgramOutputCache`. + """ + if not hasattr(app.env, 'programoutput_cache'): + app.env.programoutput_cache = ProgramOutputCache() + + +def setup(app): + app.add_config_value('programoutput_prompt_template', + '$ {command}\n{output}', 'env') + app.add_directive('program-output', ProgramOutputDirective) + app.add_directive('command-output', ProgramOutputDirective) + app.connect('builder-inited', init_cache) + app.connect('doctree-read', run_programs) + metadata = { + 'parallel_read_safe': True + } + return metadata diff --git a/doc/source/about_no_title.rst b/doc/source/about_no_title.rst index 8e48a9b333a6..45d2163d9b0e 100644 --- a/doc/source/about_no_title.rst +++ b/doc/source/about_no_title.rst @@ -1,4 +1,4 @@ -GDAL is a translator library for raster and vector geospatial data formats that is released under an MIT style Open Source :ref:`license` by the `Open Source Geospatial Foundation`_. As a library, it presents a single raster abstract data model and single vector abstract data model to the calling application for all supported formats. It also comes with a variety of useful command line utilities for data translation and processing. The `NEWS`_ page describes the August 2024 GDAL/OGR 3.9.2 release. +GDAL is a translator library for raster and vector geospatial data formats that is released under an MIT style Open Source :ref:`license` by the `Open Source Geospatial Foundation`_. As a library, it presents a single raster abstract data model and single vector abstract data model to the calling application for all supported formats. It also comes with a variety of useful command line utilities for data translation and processing. The `NEWS`_ page describes the November 2024 GDAL/OGR 3.10.0 release. .. only:: html @@ -9,7 +9,7 @@ GDAL is a translator library for raster and vector geospatial data formats that :target: `Open Source Geospatial Foundation`_ .. _`Open Source Geospatial Foundation`: http://www.osgeo.org/ -.. _`NEWS`: https://github.com/OSGeo/gdal/blob/v3.9.2/NEWS.md +.. _`NEWS`: https://github.com/OSGeo/gdal/blob/v3.10.0/NEWS.md See :ref:`software_using_gdal` diff --git a/doc/source/api/csharp/csharp_compile_legacy.rst b/doc/source/api/csharp/csharp_compile_legacy.rst index da817c98207a..e9579c045e3f 100644 --- a/doc/source/api/csharp/csharp_compile_legacy.rst +++ b/doc/source/api/csharp/csharp_compile_legacy.rst @@ -84,7 +84,7 @@ To test the compiled binaries, you can use: nmake /f makefile.vc test` -This command will invoke some of the sample applications. +This command will invoke some of the sample applications. .. note:: For the tests to work the location of the proj and gdal DLLs should be available in the PATH. @@ -93,7 +93,7 @@ Using MONO on Windows If you have the Windows version of the MONO package installed you can compile the C# code using the MONO compiler. In this case uncomment the following entry in csharp.opt: -:program:`MONO = YES` +:program:`MONO = YES` .. note:: mcs.exe must be in the PATH. @@ -165,7 +165,7 @@ To test the compiled binaries, you can use: nmake test -This command will invoke some of the sample applications. +This command will invoke some of the sample applications. .. note:: For the tests to work the location of the proj and gdal libraries should be available in the PATH. @@ -179,8 +179,4 @@ To run one of the prebuilt executables - you can run them with Mono as follows : :program:`mono GDALInfo.exe` Both the managed libraries (i.e. the DLLs) and the unmanaged libraries must be available to Mono. -This is in more detail in `the Mono documentation `__ - -.. note:: This document was amended from the previous version at `https://trac.osgeo.org/gdal/wiki/GdalOgrCsharpCompile `__ - - +This is in more detail in `the Mono documentation `__ diff --git a/doc/source/api/csharp/csharp_raster.rst b/doc/source/api/csharp/csharp_raster.rst index ac0e23ea40b8..fde6af99db4b 100644 --- a/doc/source/api/csharp/csharp_raster.rst +++ b/doc/source/api/csharp/csharp_raster.rst @@ -15,40 +15,40 @@ The :file:`Band` class contains the following :file:`ReadRaster`/:file:`WriteRas .. code-block:: C# - public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, + + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, + + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, + + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, + + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace){} - + public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, i nt buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace){} - - public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, + + public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace){} The only difference between these functions is the actual type of the buffer parameter. @@ -76,7 +76,7 @@ When reading the image this way the C# API will copy the image data between the band.ReadRaster(0, 0, width, height, r, width, height, 0, 0); // Copying the pixels into the C# bitmap int i, j; - for (i = 0; i< width; i++) + for (i = 0; i< width; i++) { for (j=0; j`__ diff --git a/doc/source/api/index.rst b/doc/source/api/index.rst index 127aea2f66a1..652fdd2e39df 100644 --- a/doc/source/api/index.rst +++ b/doc/source/api/index.rst @@ -81,18 +81,9 @@ API ---------- .. toctree:: - :maxdepth: 1 + :maxdepth: 2 - python_bindings - python/raster_api - python/vector_api - python/spatial_ref_api - python/mdim_api - python/utilities - python/general - python/osgeo - python_gotchas - python_samples + python/index `Java API <../java/index.html>`_ @@ -117,7 +108,6 @@ API Go Julia - Lua Original Node.js bindings Node.js fork with full Promise-based async and TypeScript support Perl @@ -126,10 +116,6 @@ API Ruby Rust - .. warning:: - For Perl, since GDAL 3.5 the link `Perl `__ is deprecated, use above link instead. - - There are also more Pythonic ways of using the vector/OGR functions with diff --git a/doc/source/api/python/data/byte.tif b/doc/source/api/python/data/byte.tif new file mode 100644 index 000000000000..6fddac128624 Binary files /dev/null and b/doc/source/api/python/data/byte.tif differ diff --git a/doc/source/api/python/general.rst b/doc/source/api/python/general.rst index 7c7cb58a19ab..d0828f134f8b 100644 --- a/doc/source/api/python/general.rst +++ b/doc/source/api/python/general.rst @@ -5,8 +5,8 @@ .. _python_general: -Python General API -================== +General API +=========== Configuration Management ------------------------ @@ -95,6 +95,26 @@ Error Handling File Management --------------- +osgeo.gdal_fsspec module +++++++++++++++++++++++++ + +.. automodule:: osgeo.gdal_fsspec + :members: + :undoc-members: + :show-inheritance: + :noindex: + +osgeo.gdal.VSIFile class +++++++++++++++++++++++++ + +.. autoclass:: osgeo.gdal.VSIFile + :members: + :undoc-members: + :noindex: + +Low level functions ++++++++++++++++++++ + .. autofunction:: osgeo.gdal.CloseDir .. autofunction:: osgeo.gdal.CopyFile diff --git a/doc/source/api/python/index.rst b/doc/source/api/python/index.rst new file mode 100644 index 000000000000..b7e93f6a05ef --- /dev/null +++ b/doc/source/api/python/index.rst @@ -0,0 +1,22 @@ +.. _python_api: + +================================================================================ +Python API +================================================================================ + +.. only:: not latex + + .. toctree:: + :maxdepth: 2 + + python_bindings + python_examples + osgeo + raster_api + vector_api + spatial_ref_api + mdim_api + utilities + general + python_gotchas + python_samples diff --git a/doc/source/api/python/mdim_api.rst b/doc/source/api/python/mdim_api.rst index 4cfbdbf7f6ef..7bd945627b83 100644 --- a/doc/source/api/python/mdim_api.rst +++ b/doc/source/api/python/mdim_api.rst @@ -5,8 +5,8 @@ .. _python_mdim_api: -Python Multi-dimensional array API -================================== +Multi-dimensional array API +=========================== .. autoclass:: osgeo.gdal.Group :members: diff --git a/doc/source/api/python/osgeo.gdal_fsspec.rst b/doc/source/api/python/osgeo.gdal_fsspec.rst new file mode 100644 index 000000000000..2b1bbe35b138 --- /dev/null +++ b/doc/source/api/python/osgeo.gdal_fsspec.rst @@ -0,0 +1,12 @@ +.. + The documentation displayed on this page is automatically generated from + Python docstrings. See https://gdal.org/development/dev_documentation.html + for information on updating this content. + +osgeo.gdal_fsspec module +======================== + +.. automodule:: osgeo.gdal_fsspec + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/python/osgeo.rst b/doc/source/api/python/osgeo.rst index d10dfdded4ba..920a0c0de2ef 100644 --- a/doc/source/api/python/osgeo.rst +++ b/doc/source/api/python/osgeo.rst @@ -1,7 +1,7 @@ .. _python_osgeo: -Miscellaneous Python API -======================== +Submodules +========== Submodules @@ -12,6 +12,7 @@ Submodules osgeo.gdal osgeo.gdal_array + osgeo.gdal_fsspec osgeo.gdalconst osgeo.gnm osgeo.ogr diff --git a/doc/source/api/python_bindings.rst b/doc/source/api/python/python_bindings.rst similarity index 100% rename from doc/source/api/python_bindings.rst rename to doc/source/api/python/python_bindings.rst diff --git a/doc/source/api/python/python_examples.myst b/doc/source/api/python/python_examples.myst new file mode 100644 index 000000000000..7d6ce8c70b8d --- /dev/null +++ b/doc/source/api/python/python_examples.myst @@ -0,0 +1,121 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst +kernelspec: + display_name: Python 3 + language: python + name: python3 +--- + +# Examples + +## Getting information on a raster dataset using dedicated methods + +The following snippet uses individual API methods to retrieve characters of +a GDAL raster dataset and its bands. + +```{code-cell} + +from osgeo import gdal +import json + +gdal.UseExceptions() + +ds = gdal.Open("data/byte.tif") +print(f"Width: {ds.RasterXSize}") +print(f"Height: {ds.RasterYSize}") +print(f"Number of bands: {ds.RasterCount}") +``` + +```{code-cell} +srs = ds.GetSpatialRef() +srs_unit = "" +if srs: + srs_as_projjson = json.loads(srs.ExportToPROJJSON()) + print("SRS:") + srs_type = srs_as_projjson["type"] + print(f" Type: {srs_type}") + name = srs_as_projjson["name"] + print(f" Name: {name}") + if "id" in srs_as_projjson: + id = srs_as_projjson["id"] + authority = id["authority"] + code = id["code"] + print(f" Id: {authority}:{code}") + srs_unit = " " + srs_as_projjson["coordinate_system"]["axis"][0]["unit"] +``` + +```{code-cell} +geotransform = ds.GetGeoTransform() +if geotransform[2] == 0 and geotransform[4] == 0: + print(f"Upper-left corner georeferenced position: X={geotransform[0]}{srs_unit}, Y={geotransform[3]}{srs_unit}") + print(f"Horizontal resolution: {geotransform[1]}{srs_unit}") + print(f"Vertical resolution: {geotransform[5]}{srs_unit} (negative value indicates a north-up image)") +else: + print(f"Geotransformation matrix: {geotransform}") +print(f"Metadata: {ds.GetMetadata()}") +``` + +```{code-cell} +for idx, band in enumerate(ds): + print(f"Band {idx+1}:") + print(f" Data type: {gdal.GetDataTypeName(band.DataType)}") + block_width, block_height = band.GetBlockSize() + print(f" Block width: {block_width}") + print(f" Block height: {block_height}") + print(f" Metadata: {band.GetMetadata()}") +``` + +```{code-cell} +:tags: [remove-output] + +# Explicitly close the dataset. May be needed in creation/update scenarios, to +# make sure all data is properly flushed to storage, or even in read-only +# scenarios, if you want to delete the file afterwards (on Windows). +# You may also use a context manager with "with gdal.Open(...) as ds" as shown +# in later examples. +ds.Close() +``` + +## Getting information on a raster dataset using gdal.Info() + +The following snippet uses the {py:func}`osgeo.gdal.Info()` method to retrieve characters of +a GDAL raster dataset and its bands, as a JSON document. + +```{code-cell} +:tags: [hide-output] + +from osgeo import gdal +import pprint + +gdal.UseExceptions() + +with gdal.Open("data/byte.tif") as ds: + info = gdal.Info(ds, format='json') + del info["stac"] # to avoid cluttering below output + pprint.pprint(info, indent=2, width=100) +``` + +## Reading a whole raster as a numpy array + +The following snippet uses the {py:func}`osgeo.gdal.Dataset.ReadAsArray()` +method to retrieve the pixel values of all the bands of a dataset as a +[numpy array](https://numpy.org/doc/stable/reference/generated/numpy.array.html). + +A 2D array is returned for a single band image. A 3D array, with first dimension +being the band one, is returned for images with multiple bands. + +```{code-cell} +:tags: [hide-output] + +from osgeo import gdal + +gdal.UseExceptions() + +with gdal.Open("data/byte.tif") as ds: + array = ds.ReadAsArray() + print(array) +``` diff --git a/doc/source/api/python_gotchas.rst b/doc/source/api/python/python_gotchas.rst similarity index 99% rename from doc/source/api/python_gotchas.rst rename to doc/source/api/python/python_gotchas.rst index e1d9592e37d2..e10f84a90cf6 100644 --- a/doc/source/api/python_gotchas.rst +++ b/doc/source/api/python/python_gotchas.rst @@ -1,7 +1,7 @@ .. _python_gotchas: ================================================================================ -Python Gotchas in the GDAL and OGR Python Bindings +Gotchas in the GDAL and OGR Python Bindings ================================================================================ This page lists aspects of GDAL's and OGR's Python bindings that may catch Python programmers by surprise. @@ -232,7 +232,7 @@ But you can do something like this instead: from osgeo import gdal - class GdalErrorHandler(object): + class GdalErrorHandler: def __init__(self): self.err_level = gdal.CE_None self.err_no = 0 diff --git a/doc/source/api/python_samples.rst b/doc/source/api/python/python_samples.rst similarity index 97% rename from doc/source/api/python_samples.rst rename to doc/source/api/python/python_samples.rst index a2831f63ffaa..bb285fe21da7 100644 --- a/doc/source/api/python_samples.rst +++ b/doc/source/api/python/python_samples.rst @@ -1,7 +1,7 @@ .. _python_samples: ================================================================================ -Python Sample scripts +Sample scripts ================================================================================ The following are sample scripts intended to give an idea how to use the @@ -47,6 +47,7 @@ Python Raster Sample scripts - hsv_merge: Merge greyscale image into RGB image as intensity in HSV space. - gdal_ls: Display the list of files in a virtual directory, like /vsicurl or /vsizip - gdal_cp: Copy a virtual file + - gdal_minmax_location: returns the location where min/max values of a raster are hit. Python Vector Sample scripts ------------------------------ diff --git a/doc/source/api/python/raster_api.rst b/doc/source/api/python/raster_api.rst index f0172eff0806..f5f43ab3bf80 100644 --- a/doc/source/api/python/raster_api.rst +++ b/doc/source/api/python/raster_api.rst @@ -5,8 +5,8 @@ .. _python_raster_api: -Python Raster API -================= +Raster API +========== This page contains classes, methods, functions that relate to the GDAL :ref:`raster_data_model`: diff --git a/doc/source/api/python/spatial_ref_api.rst b/doc/source/api/python/spatial_ref_api.rst index 6337d2a5d6e9..9a9038c0d625 100644 --- a/doc/source/api/python/spatial_ref_api.rst +++ b/doc/source/api/python/spatial_ref_api.rst @@ -5,8 +5,8 @@ .. _python_spatial_ref_api: -Python Spatial Reference System API -=================================== +Spatial Reference System API +============================ This page contains classes, methods and functions that relate to spatial reference systems: diff --git a/doc/source/api/python/utilities.rst b/doc/source/api/python/utilities.rst index 372ed3df48df..3fb8b808f679 100644 --- a/doc/source/api/python/utilities.rst +++ b/doc/source/api/python/utilities.rst @@ -5,8 +5,8 @@ .. _python_utilities: -Python Utilities -================ +Utilities API +============= Raster Utilities ---------------- diff --git a/doc/source/api/python/vector_api.rst b/doc/source/api/python/vector_api.rst index 2c041aba75f5..034a46ce2dd9 100644 --- a/doc/source/api/python/vector_api.rst +++ b/doc/source/api/python/vector_api.rst @@ -5,8 +5,8 @@ .. _python_vector_api: -Python Vector API -================= +Vector API +========== This page contains classes, methods, functions that relate to the GDAL :ref:`vector_data_model`. The :py:class:`Driver` and :py:class:`Dataset` classes, which applies to both vector and raster data, are documented with the :ref:`python_raster_api`. diff --git a/doc/source/api/vector_c_api.rst b/doc/source/api/vector_c_api.rst index ea70e352227c..65dc4074b266 100644 --- a/doc/source/api/vector_c_api.rst +++ b/doc/source/api/vector_c_api.rst @@ -14,3 +14,6 @@ ogr_core.h and ogr_api.h: Vector C API .. doxygenfile:: ogr_api.h :project: api + +.. doxygenfile:: gdal_adbc.h + :project: api diff --git a/doc/source/community/code_of_conduct.rst b/doc/source/community/code_of_conduct.rst index 9dc38d42ac5b..b151edb5daf9 100644 --- a/doc/source/community/code_of_conduct.rst +++ b/doc/source/community/code_of_conduct.rst @@ -19,7 +19,7 @@ claims any affiliation with the GDAL project. It applies to in-person events (such as conferences and related social events), IRC, public and private mailing lists, the issue tracker, the wiki, blogs, -Twitter, and any other forums which the community uses for communication and +social media, and any other forums which the community uses for communication and interactions. This code is not exhaustive or complete. It serves to distill our common diff --git a/doc/source/community/index.rst b/doc/source/community/index.rst index 9327bf3ba51c..2ebfa71939c3 100644 --- a/doc/source/community/index.rst +++ b/doc/source/community/index.rst @@ -27,6 +27,7 @@ Code of Conduct code_of_conduct +.. _mailing_list: Mailing List ------------ diff --git a/doc/source/conf.py b/doc/source/conf.py index f95b1517e968..7218d202100b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -43,9 +43,10 @@ doc_version = open(version_file).read().strip() gdal_version = gdal.__version__ gdal_version_stripped = gdal_version - pos_dev = gdal_version_stripped.find("dev") - if pos_dev > 0: - gdal_version_stripped = gdal_version_stripped[0:pos_dev] + for suffix in ["dev", "beta"]: + pos_suffix = gdal_version_stripped.find(suffix) + if pos_suffix > 0: + gdal_version_stripped = gdal_version_stripped[0:pos_suffix] if doc_version.strip() != gdal_version_stripped: logger.warn( @@ -67,10 +68,13 @@ "breathe", "configoptions", "driverproperties", + "cli_example", "source_file", "sphinx.ext.napoleon", "sphinxcontrib.jquery", + "sphinxcontrib_programoutput_gdal", "sphinxcontrib.spelling", + "myst_nb", ] # Add any paths that contain templates here, relative to this directory. @@ -83,6 +87,7 @@ "substitutions.rst", "programs/options/*.rst", "api/python/modules.rst", + "gdal_rtd/README.md", ] # Prevents double hyphen (--) to be replaced by Unicode long dash character @@ -111,6 +116,12 @@ .. |offline-download| replace:: {offline_download_text} """ +source_suffix = { + ".rst": "restructuredtext", + ".ipynb": "myst-nb", + ".myst": "myst-nb", +} + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -132,7 +143,7 @@ "canonical_url": "https://gdal.org/", # Trailing slash needed to have correct URLs "analytics_id": "", # Provided by Google in your dashboard "logo_only": True, - "display_version": True, + "version_selector": True, "prev_next_buttons_location": "both", "style_external_links": False, #'vcs_pageview_mode': '', @@ -143,13 +154,16 @@ #'navigation_depth': 4, "includehidden": True, "titles_only": False, + "flyout_display": "attached", } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] -html_extra_path = ["../build/html_extra"] + +# For generated content and robots.txt +html_extra_path = ["../build/html_extra", "extra_path"] # If true, links to the reST sources are added to the pages. html_show_sourcelink = False @@ -489,6 +503,7 @@ preamble = r""" \ifdefined\DeclareUnicodeCharacter \DeclareUnicodeCharacter{2032}{$'$}% prime + \DeclareUnicodeCharacter{200B}{{\hskip 0pt}} \fi """ @@ -571,3 +586,10 @@ spelling_ignore_contributor_names = False spelling_word_list_filename = ["spelling_wordlist.txt"] + +# -- myst-nb -------------------------------------------------- + +# Sets `text/plain` as the highest priority for `spelling` output. +nb_mime_priority_overrides = [ + ("spelling", "text/plain", 0), +] diff --git a/doc/source/development/building_from_source.rst b/doc/source/development/building_from_source.rst index 6a067888836e..abe454c68167 100644 --- a/doc/source/development/building_from_source.rst +++ b/doc/source/development/building_from_source.rst @@ -224,6 +224,36 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory. `CMAKE_SKIP_INSTALL_RPATH `__ variable is not set. +Resource files embedding +++++++++++++++++++++++++ + +Starting with GDAL 3.11, if a C23-compatible compiler is used, such as +clang >= 19 or GCC >= 15, it is possible to embed resource files inside +the GDAL library, without relying on resource files to be available on the file +system (such resource files are located through an hard-coded +path at build time in ``${CMAKE_INSTALL_PREFIX}/share/gdal``, or at run-time +through the :config:`GDAL_DATA` configuration option). + +The following CMake options control that behavior: + +.. option:: EMBED_RESOURCE_FILES=ON/OFF + + .. versionadded:: 3.11 + + Default is OFF for shared library builds (BUILD_SHARED_LIBS=ON), and ON + for static library builds (BUILD_SHARED_LIBS=OFF). + When ON, resource files needed by GDAL will be embedded into the GDAL library + and/or relevant plugins. + +.. option:: USE_ONLY_EMBEDDED_RESOURCE_FILES=ON/OFF + + .. versionadded:: 3.11 + + Even if EMBED_RESOURCE_FILES=ON, GDAL will still try to locate resource + files on the file system by default , and fallback to the embedded version if + not found. By setting USE_ONLY_EMBEDDED_RESOURCE_FILES=ON, no attempt + at locating resource files on the file system is made. Default is OFF. + CMake package dependent options +++++++++++++++++++++++++++++++ @@ -1202,27 +1232,6 @@ capabilities in GMLJP2v2 generation. Control whether to use LibXml2. Defaults to ON when LibXml2 is found. -LURATECH -******** - -The Luratech JPEG2000 SDK (closed source/proprietary) is required for the -:ref:`raster.jp2lura` driver. - -LURATECH_ROOT or CMAKE_PREFIX_PATH should point to the directory of the SDK. - -.. option:: LURATECH_INCLUDE_DIR - - Path to the include directory with the ``lwf_jp2.h`` header file. - -.. option:: LURATECH_LIBRARY - - Path to library file lib_lwf_jp2.a / lwf_jp2.lib - -.. option:: GDAL_USE_LURATECH=ON/OFF - - Control whether to use LURATECH. Defaults to ON when LURATECH is found. - - LZ4 *** @@ -2546,5 +2555,5 @@ crashes will occur at runtime (often at process termination with a Autoconf/nmake (GDAL versions < 3.5.0) -------------------------------------------------------------------------------- -See https://trac.osgeo.org/gdal/wiki/BuildHints for hints for GDAL < 3.5 +See http://web.archive.org/https://trac.osgeo.org/gdal/wiki/BuildHints for hints for GDAL < 3.5 autoconf and nmake build systems. diff --git a/doc/source/development/dev_documentation.rst b/doc/source/development/dev_documentation.rst index 0dd69130f4c0..78bc10d43ab9 100644 --- a/doc/source/development/dev_documentation.rst +++ b/doc/source/development/dev_documentation.rst @@ -341,6 +341,46 @@ To reference a method or function:: :cpp:func:`MyClass::MyMethod` :cpp:func:`MyFunction` + +Command-line program usage +-------------------------- + +To document a command-line tool, use the ``example`` directive. +An example may have a title as well as an id that can be used to generate +a cross-reference from the same document. + +.. code-block:: rst + + .. example:: + :title: Listing files + :id: basic-ls + + Files can be listed as follows: + + .. code-block:: bash + + ls + + The ``ls`` command is demonstrated in :example:`basic-ls`. + +If output of the command is to be included in the listing, the code language +should be set to ``console``: + +.. code-block:: rst + + .. code-block:: console + + $ gdalinfo --version + GDAL 3.4.1, released 2021/12/27 + +To run the command and collect its output when the documentation is built, use the ``command-output`` directive. + +.. code-block:: rst + + .. command-output:: ogrinfo poly.shp + :cwd: ../../../autotest/ogr/data + + .. _config_option_syntax: Define and reference configuration options @@ -407,3 +447,44 @@ Use ``describe`` to document create parameters:: .. describe:: WORLDFILE=YES Force the generation of an associated ESRI world file (with the extension .wld). + +MyST-NB - Executable notebooks +############################## + +Quoting `MyST-NB documentation `__, +"MyST-NB is a module within the Executable Books Project, an international +collaboration to build open source tools that facilitate publishing computational +narratives using the Jupyter ecosystem. It is also a core component of Jupyter Book." + +The documentation is written in a special markdown dialect, MyST Markdown, +that can include code cells: + +.. code-block:: markdown + + ```{code-cell} + :tags: [hide-output] + + from osgeo import gdal + import pprint + + gdal.UseExceptions() + + with gdal.Open("data/byte.tif") as ds: + info = gdal.Info(ds, format='json') + del info["stac"] # to avoid cluttering below output + pprint.pprint(info, indent=2, width=100) + ``` + +See :file:`doc/source/api/python/python_examples.myst` for an example. + +Consult how to author `text-based notebooks `__ +for more details.` + +Building full GDAL documentation, even in incremental mode, is rather slow. +It is possible to partly render to HTML a MyST file with: + +.. code-block:: shell + + $ mystnb-docutils-html5 --nb-read-as-md=true source/api/python/python_examples.myst > out.html + +You will get some warnings, but executable run will be executed and rendered. diff --git a/doc/source/development/index.rst b/doc/source/development/index.rst index 59902fdbcfe5..c3e443578dc2 100644 --- a/doc/source/development/index.rst +++ b/doc/source/development/index.rst @@ -14,4 +14,5 @@ Development testing dev_documentation cmake + rfc_process rfc/index diff --git a/doc/source/development/rfc/index.rst b/doc/source/development/rfc/index.rst index f0763fe8d0ca..fc7714e67617 100644 --- a/doc/source/development/rfc/index.rst +++ b/doc/source/development/rfc/index.rst @@ -106,3 +106,5 @@ RFC list rfc97_feature_and_fielddefn_sealing rfc98_build_requirements_gdal_3_9 rfc99_geometry_coordinate_precision + rfc101_raster_dataset_threadsafety + rfc102_embedded_resources diff --git a/doc/source/development/rfc/rfc101_raster_dataset_threadsafety.rst b/doc/source/development/rfc/rfc101_raster_dataset_threadsafety.rst new file mode 100644 index 000000000000..be9ff44135fe --- /dev/null +++ b/doc/source/development/rfc/rfc101_raster_dataset_threadsafety.rst @@ -0,0 +1,482 @@ +.. _rfc-101: + +=================================================================== +RFC 101: Raster dataset read-only thread-safety +=================================================================== + +============== ============================================= +Author: Even Rouault +Contact: even.rouault @ spatialys.com +Started: 2024-Aug-29 +Status: Adopted, implemented +Target: GDAL 3.10 +============== ============================================= + +Summary +------- + +This RFC enables users to get instances of :cpp:class:`GDALDataset` +(and their related objects such as :cpp:class:`GDALRasterBand`) that are +thread-safe for read-only raster operations, that is such instances can +be safely used from multiple threads without locking. + +Terminology +----------- + +The exact meaning of the terms ``thread-safe`` or ``re-entrant`` is not fully +standardized. We will use here the `QT definitions `__. +In particular, a C function or C++ method is said to be re-entrant if it can +be called simultaneously from multiple threads, *but* only if each invocation +uses its own data/instance. On the contrary, it is thread-safe is if can be +called on the same data/instance (so thread-safe is stronger than re-entrant) + +Motivation +---------- + +A number of raster algorithms can be designed to read chunks of a raster in +an independent and concurrent way, with resulting speed-ups when using +multi-threading. Currently, given a GDALDataset instance is not thread-safe, +this requires either to deal with I/O in a single thread, or through a mutex +to protect against concurrent use, or one needs to open a separate GDALDataset +for each worker thread. Both approaches can complicate the writing of such +algorithms. The enhancement of this RFC aims at providing a special GDALDataset +instance that can be used safely from multiple threads. Internally, it does use +one GDALDataset per thread, but hides this implementation detail to the user. + +C and C++ API extensions +------------------------ + +A new ``GDAL_OF_THREAD_SAFE`` opening flag is added to be specified to +:cpp:func:`GDALOpenEx` / :cpp:func:`GDALDataset::Open`. This flag is for now +mutually exclusive with ``GDAL_OF_VECTOR``, ``GDAL_OF_MULTIDIM_RASTER`` and +``GDAL_OF_UPDATE``. That is this flag is only meant for read-only raster +operations (``GDAL_OF_RASTER | GDAL_OF_THREAD_SAFE``). + +To know if a given dataset can be used in a thread-safe way, the following +C++ method is added to the GDALDataset class: + +.. code-block:: c++ + + /** Return whether this dataset, and its related objects (typically raster + * bands), can be called for the intended scope. + * + * Note that in the current implementation, nScopeFlags should be set to + * GDAL_OF_RASTER, as thread-safety is limited to read-only operations and + * excludes operations on vector layers (OGRLayer) or multidimensional API + * (GDALGroup, GDALMDArray, etc.) + * + * This is the same as the C function GDALDatasetIsThreadSafe(). + * + * @since 3.10 + */ + bool IsThreadSafe(int nScopeFlags) const; + + +The corresponding C function is added: + +.. code-block:: c + + bool GDALDatasetIsThreadSafe(GDALDatasetH hDS, int nScopeFlags, + CSLConstList papszOptions); + + +A new C++ function, GDALGetThreadSafeDataset, is added with two forms: + +.. code-block:: c++ + + std::unique_ptr GDALGetThreadSafeDataset(std::unique_ptr poDS, int nScopeFlags); + + GDALDataset* GDALGetThreadSafeDataset(GDALDataset* poDS, int nScopeFlags); + +This function accepts a (generally non thread-safe) source dataset and return +a new dataset that is a thread-safe wrapper around it, or the source dataset if +it is already thread-safe. +The nScopeFlags argument must be compulsory set to GDAL_OF_RASTER to express that +the intended scope is read-only raster operations (other values will result in +an error and a NULL returned dataset). +This function is used internally by GDALOpenEx() when the GDAL_OF_THREAD_SAFE +flag is passed to wrap the dataset returned by the driver. +The first form takes ownership of the source dataset. The second form does not, +but references it internally, and assumes that its lifetime will be longer than +the lifetime of the returned thread-safe dataset. Note that the second form does +increase the reference count on the passed dataset while it is being used, so +patterns like the following one are valid: + +.. code-block:: c++ + + auto poDS = GDALDataset::Open(...); + GDALDataset* poThreadSafeDS = GDALGetThreadSafeDataset(poDS, GDAL_OF_RASTER | GDAL_OF_THREAD_SAFE); + poDS->ReleaseRef(); // can be done here, or any time later + if (poThreadSafeDS ) + { + // ... do something with poThreadSafeDS ... + poThreadSafeDS->ReleaseRef(); + } + + +For proper working both when a new dataset is returned or the passed one if it +is already thread-safe, :cpp:func:`GDALDataset::ReleaseRef()` (and not delete or +GDALClose()) must be called on the returned dataset. + + +The corresponding C function for the second form is added: + +.. code-block:: c + + GDALDatasetH GDALGetThreadSafeDataset(GDALDatasetH hDS, int nScopeFlags, CSLConstList papszOptions); + + +Usage examples +-------------- + +Example of a function processing a whole dataset passed as a filename: + +.. code-block:: c++ + + void foo(const char* pszFilename) + { + auto poDS = std::unique_ptr(GDALDataset::Open( + pszFilename, GDAL_OF_RASTER | GDAL_OF_THREAD_SAFE | GDAL_OF_VERBOSE_ERROR)); + if( !poDS ) + { + return; + } + + // TODO: spawn threads using poDS + } + + +Example of a function processing a whole dataset passed as an object: + +.. code-block:: c++ + + void foo(GDALDataset* poDS) + { + GDALDataset* poThreadSafeDS = GDALGetThreadSafeDataset(poDS, GDAL_OF_RASTER); + if( poThreadSafeDS ) + { + // TODO: spawn threads using poThreadSafeDS + + poThreadSafeDS->ReleaseRef(); + } + else + { + // TODO: Serial version of the algorithm. It can happen if + // poDS is a on-the-fly dataset. + } + } + + +Example of a function processing a single band passed as an object: + +.. code-block:: c++ + + void foo(GDALRasterBand* poBand) + { + GDALDataset* poThreadSafeDS = nullptr; + GDALRasterBand* poThreadSafeBand = nullptr; + GDALDataset* poDS = poBand->GetDataset(); + // Check that poBand has a matching owing dataset + if( poDS && poDS->GetRasterBand(poBand->GetBand()) == poBand ) + { + poThreadSafeDS = GDALGetThreadSafeDataset(poDS, GDAL_OF_RASTER); + if( poThreadSafeDS ) + poThreadSafeBand = poThreadSafeDS->GetBand(poBand->GetBand()); + } + + if( poThreadSafeBand ) + { + // TODO: spawn threads using poThreadSafeBand + + poThreadSafeDS->ReleaseRef(); + } + else + { + // TODO: Serial version of the algorithm. It can happen if + // poBand is a on-the-fly band, or a "detached" band, such as a + // mask band, or an overview band as returned by some drivers. + } + } + + +SWIG bindings +------------- + +The new C macro and functions are bound to SWIG as: + +- ``gdal.OF_THREAD_SAFE`` +- :py:func:`Dataset.IsThreadSafe(nScopeFlags)` +- :py:func:`Dataset.GetThreadSafeDataset(nScopeFlags)`. The Python + implementation of this method takes care of keeping a reference on the source + dataset in the returned thread-safe dataset, so the user does not have to + care about their respective lifetimes. + +Usage and design limitations +---------------------------- + +* As implied by the RFC title, the scope of thread-safety is restricted to + **raster** and **read-only** operations. + +* For GDALDataset instances pointing to a file on the regular filesystem, the + limitation of the maximum number of file descriptor opened by a process + (1024 on most Linux systems) could be hit if working with a sufficiently large + number of worker threads and/or instances of GDALThreadSafeDataset. + +* The generic implementation of GDALGetThreadSafeDataset assumes that the + source dataset can be re-opened by its name (GetDescription()), which is the + case for datasets opened by GDALOpenEx(). A special implementation is also + made for dataset instances of the MEM driver. But, there is currently no + support for creating a thread-safe dataset wrapper on on-the-fly datasets + returned by some algorithms (e.g GDALTranslate() or GDALWarp() with VRT as + the output driver and with an empty filename, or custom GDALDataset + implementation by external code). + +* Inherent to the selected approach, there is a band block cache per thread, and + thus no sharing of cached blocks between threads. + However, this should not be a too severe limitation for algorithms where + threads process independent regions of the raster, hence reuse of cached blocks + would be non-existent or low. Optimal algorithms will make sure to work on + regions of interest aligned on the block size (this advice also applies for + the current approach of manually opening a dataset for each worker thread). + +* Due to implementation limitations, :cpp:func:`GDALRasterBand::GetDefaultRAT` + on a GDALThreadSafeDataset instance only works if the RAT is an instance of + :cpp:class:`GDALDefaultRasterAttributeTable`. An error is emitted if + this is not the case. This could potentially be extended to work with any + subclass of :cpp:class:`GDALRasterAttributeTable` but with significant + additional coding to create a thread-safe wrapper. (GDALDefaultRasterAttributeTable + is intrinsically thread-safe for read-only operations). This is not perceived + as a limitation for the intended use cases of this RFC (reading pixel values + in parallel). + +* Some drivers, like netCDF, and HDF5 in some builds, use a global lock around + each call to their APIs, due to the underlying libraries not being re-entrant. + Obviously scalability of GDALThreadSafeDataset will be limited by such global + lock. + But this is no different than the approach of opening as many dataset as + worker threads. + +Implementation details +---------------------- + +(This section is mostly of interest for developers familiar with GDAL internals +and may be skipped by users of the GDAL API) + +The gist of the implementation lies in a new file ``gcore/gdalthreadsafedataset.cpp`` +which defines several classes (internal details): + +- ``GDALThreadSafeDataset`` extending :cpp:class:`GDALProxyDataset`. + Instances of that class are returned by GDALGetThreadSafeDataset(). + On instantiation, it creates as many GDALThreadSafeRasterBand instances as + the number of bands of the source dataset. + All virtual methods of GDALDataset are redefined by GDALProxyDataset. + GDALThreadSafeDataset overloads its ReferenceUnderlyingDataset method, so that + a thread-local dataset is opened the first-time a thread calls a method on + the GDALThreadSafeDataset instance, cached for later use, and method call is + generally forwarded to it. There are exceptions for methods like + :cpp:func:`GDALDataset::GetSpatialRef`, :cpp:func:`GDALDataset::GetGCPSpatialRef`, + :cpp:func:`GDALDataset::GetGCPs`, :cpp:func:`GDALDataset::GetMetadata`, + :cpp:func:`GDALDataset::GetMetadataItem` that return non-primitive types + where the calls are forwarded to the dataset used to construct GDALThreadSafeDataset, + with a mutex being taken around them. If the call was otherwise forwarded to + a thread-local instance, there would be a risk of use-after-free situations + when the returned value is used by different threads. + +- ``GDALThreadSafeRasterBand`` extending :cpp:class:`GDALProxyRasterBand`. + On instantiation, it creates child GDALThreadSafeRasterBand instances for + band mask and overviews. + Its ReferenceUnderlyingRasterBand method calls ReferenceUnderlyingDataset + on the GDALThreadSafeDataset instance to get a thread-local dataset, fetches + the appropriate thread-local band and generally forwards its the method call. + There are exceptions for methods like + :cpp:func:`GDALRasterBand::GetUnitType`, :cpp:func:`GDALRasterBand::GetMetadata`, + :cpp:func:`GDALRasterBand::GetMetadataItem` that return non-primitive types where + the calls are forwarded to the band used to construct GDALThreadSafeRasterBand, + with a mutex being taken around them, and the returned value being . + +- ``GDALThreadLocalDatasetCache``. Instances of that class use thread-local + storage. The main member of such instances is a LRU cache that maps + GDALThreadSafeDataset* instances to a thread specific GDALDataset smart pointer. + On GDALThreadSafeDataset destruction, there's code to iterate over all + alive GDALThreadLocalDatasetCache instances and evict no-longer needed entries + in them, within a per-GDALThreadLocalDatasetCache instance mutex, to avoid + issues when dealing with several instances of GDALThreadLocalDatasetCache... + Note that the existence of this mutex should not cause performance issues, since + contention on it, should be very low in real-world use cases (it could become + a bottleneck if GDALThreadSafeDataset were created and destroyed at a very + high pace) + +Two protected virtual methods are added to GDALDataset for GDALThreadSafeDataset +implementation, and may be overloaded by drivers if needed (but it is not +anticipated that drivers but the MEM driver need to do that) + +- ``bool CanBeCloned(int nScopeFlags, bool bCanShareState) const``. + This method determines if a source dataset can be "cloned" (or re-opened). + It returns true for instances returned by GDALOpenEx, for instances of the MEM + driver if ``nScopeFlags`` == ``GDAL_OF_RASTER`` (and ``bCanShareState`` is + true for instances of the MEM driver) + +- ``std::unique_ptr Clone(int nScopeFlags, bool bCanShareState) const``. + This method returns a "clone" of the dataset on which it is called, and is used + by GDALThreadSafeDataset::ReferenceUnderlyingDataset() when a thread-local + dataset is needed. + Implementation of that method must be thread-safe. + The base implementation calls GDALOpenEx() reusing the dataset name, open flags + and open option. It is overloaded in the MEM driver to return a new instance + of MEMDataset, but sharing the memory buffers with the source dataset. + +No code in drivers, but the MEM driver, is modified by the candidate +implementation. + +A few existing non-virtual methods of GDALDataset and GDALRasterBand have been +made virtual (and overloaded by GDALProxyDataset and GDALProxyRasterBand), +to avoid modifying state on the GDALThreadSafeRasterBand instance, which +wouldn't be thread-safe. + +- :cpp:func:`GDALDataset::BlockBasedRasterIO`: + it interacts with the block cache +- :cpp:func:`GDALRasterBand::GetLockedBlockRef`: + it interacts with the block cache +- :cpp:func:`GDALRasterBand::TryGetLockedBlockRef`: + it interacts with the block cache +- :cpp:func:`GDALRasterBand::FlushBlock`: + it interacts with the block cache +- :cpp:func:`GDALRasterBand::InterpolateAtPoint`: + it uses a per-band cache +- :cpp:func:`GDALRasterBand::EnablePixelTypeSignedByteWarning`: it should + already have been made virtual for GDALProxyRasterBand needs. + +Non-virtual methods :cpp:func:`GDALDataset::GetProjectionRef` and +:cpp:func:`GDALDataset::GetGCPProjection`, which cache the return value, have +been modify to apply a mutex when run on a dataset that IsThreadSafe() to be +effectively thread-safe. + +A SetThreadSafe() method has been added to :cpp:class:`OGRSpatialReference`. +When it is called, all methods of that class run under a per-instance (recursive) +mutex. This is used by GDALThreadSafeDataset for its implementation of the +:cpp:func:`GDALDataset::GetSpatialRef` and :cpp:func:`GDALDataset::GetGCPSpatialRef` +methods, such that the returned OGRSpatialReference instances are thread-safe. + +Performance +----------- + +The existing multireadtest utility that reads a dataset from multiple threads +has been extended with a -thread_safe flag to asks to use GDAL_OF_THREAD_SAFE +when opening the dataset in the main thread and use it in the worker threads, +instead of the default behavior of opening explicitly a dataset in each thread. +The thread-safe mode shows similar scalability as the default mode, sometimes +with a slightly decreased efficiency, but not in a too problematic way. + +For example on a 20x20 raster: + +.. code-block:: shell + + $ time multireadtest -t 4 -i 1000000 20x20.tif + real 0m2.084s + user 0m8.155s + sys 0m0.020s + + vs + + $ time multireadtest -thread_safe -t 4 -i 1000000 20x20.tif + real 0m2.387s + user 0m9.334s + sys 0m0.029s + + +But on a 4096x4096 raster with a number of iterations reduced to 100, the +timings between the default and thread_safe modes are very similar. + +A Python equivalent of multireadtest has been written. Scalability depends +on how much Python code is executed. If relatively few long-enough calls to +GDAL are done, scalability tends to be good due to the Python Global Interpreter +Lock (GIL) being dropped around them. If many short calls are done, the GIL +itself, or its repeated acquisition and release, becomes the bottleneck. This is +no different than using a GDALDataset per thread. + +Documentation +------------- + +Documentation for the new constant and functions will be added. The +:ref:`multithreading` page will be updated to reflect the new capability +introduced by this RFC. + +Backward compatibility +---------------------- + +No issue anticipated: the C and C++ API are extended. +The C++ ABI is modified due to additions of new virtual methods. + +Testing +------- + +Tests will be added for the new functionality, including stress tests to have +sufficiently high confidence in the correctness of the implementation for common +use cases. + +Risks +----- + +Like all code related to multi-threading, the C++ language and tooling offers +hardly any safety belt against thread-safety programming errors. So it cannot +be excluded that the implementation suffers from bugs in some edge scenarios, +or in the usage of some methods of GDALDataset, GDALRasterBand and related objects +(particularly existing non-virtual methods of those classes that could happen +to have a non thread-safe implementation) + +Design discussion +----------------- + +This paragraph discusses a number of thoughts that arose during the writing of +this RFC. + +1. A significantly different alternative could have consisted in adding native + thread-safety in each driver. But this is not realistic for the following reasons: + + * if that was feasible, it would require considerable development effort to + rework each drivers. So realistically, only a few select drivers would be updated. + + * Even updating a reduced number of drivers would be extremely difficult, in + particular the GeoTIFF one, due to the underlying library not being reentrant, + and deferred loading strategies and many state variables being modified even + by read-only APIs. And this applies to most typical drivers. + + * Due to the inevitable locks, there would be a (small) cost bore by callers + even on single-thread uses of thread-safe native drivers. + + * Some core mechanisms, particularly around the per-band block cache structures, + are not currently thread-safe. + +2. A variant of the proposed implementation that did not use thread-local storage + has been initially attempted. It stored instead a + ``std::map>`` on each GDALThreadSafeDataset + instance. This implementation was simpler, but unfortunately suffered from high + lock contention since a mutex had to be taken around each access to this map, + with the contention increasing with the number of concurrent threads. + +3. For the unusual situations where a dataset cannot be reopened and thus + GDALGetThreadSafeDataset() fails, should we provide an additional ``bForce`` + argument to force it to still return a dataset, where calls to the wrapped + dataset are protected by a mutex? This would enable to always write multi-thread + safe code, even if the access to the dataset is serialized. + Similarly we could have a + ``std::unique_ptr GDALGetThreadSafeRasterBand(GDALRasterBand* poBand, int nOpenFlags, bool bForce)`` + function that would try to use GDALGetThreadSafeDataset() internally if it + manages to identify the dataset to which the band belongs to, and otherwise would + fallback to protecting calls to the wrapped band with a mutex. + + Given the absence of evidence that such option is necessary, this has been excluded + from the scope of this RFC. + + +Related issues and PRs +---------------------- + +- Candidate implementation: https://github.com/OSGeo/gdal/pull/10746 + +- https://github.com/OSGeo/gdal/issues/8448: GTiff: Allow concurrent reading of single blocks + +Voting history +-------------- + ++1 from PSC members KurtS, JukkaR, JavierJS and EvenR diff --git a/doc/source/development/rfc/rfc102_embedded_resources.rst b/doc/source/development/rfc/rfc102_embedded_resources.rst new file mode 100644 index 000000000000..ea41f2ec985b --- /dev/null +++ b/doc/source/development/rfc/rfc102_embedded_resources.rst @@ -0,0 +1,165 @@ +.. _rfc-102: + +=================================================================== +RFC 102: Embedding resource files into libgdal +=================================================================== + +============== ============================================= +Author: Even Rouault +Contact: even.rouault @ spatialys.com +Started: 2024-Oct-01 +Status: Adopted, implemented +Target: GDAL 3.11 +============== ============================================= + +Summary +------- + +This RFC uses C23 ``#embed`` pre-processor directive, when available, +to be able to optionally embed GDAL resource files directly into libgdal. + +A similar `PROJ RFC-8 `__ has been +submitted for PROJ to embed its :file:`proj.db` and :file:`proj.ini` files. + +Motivation +---------- + +Some parts of GDAL core, mostly drivers, require external resource files located +in the filesystem. Locating these resource files is difficult for use cases where +the GDAL binaries are relocated during installation time. +One such case could be the GDAL embedded in Rasterio or Fiona binary wheels where :config:`GDAL_DATA` must be set to the directory of the resource files. +Web-assembly (WASM) use cases come also to mind as users of GDAL builds where +resources are directly included in libgdal. + +Technical solution +------------------ + +The C23 standard includes a `#embed "filename" `__ +pre-processor directive that ingests the specified filename and returns its +content as tokens that can be stored in a unsigned char or char array. + +Getting the content of a file into a variable is as simple as the following +(which also demonstrates adding a nul-terminating character when this is needed): + +.. code-block:: c + + static const char szPDS4Template[] = { + #embed "data/pds4_template.xml" + , '\0'}; + +Compiler support +---------------- + +Support for that directive is still very new. clang 19.1 is the +first compiler which has a release including it, and has an efficient +implementation of it, able to embed very large files with minimum RAM and CPU +usage. + +The development version of GCC 15 also supports it, but in a non-optimized way +for now. i.e. trying to include large files, of several tens of megabytes could +cause significant compilation time, but without impact on runtime. This is not +an issue for GDAL use cases, and there is intent from GCC developers to improve +this in the future. + +Embedding PROJ's :file:`proj.db` of size 9.1 MB with GCC 15dev at time of writing takes +18 seconds and 1.7 GB RAM, compared to 0.4 second and 400 MB RAM for clang 19, +which is still reasonable (Generating :file:`proj.db` itself from its source .sql files +takes one minute on the same system). + +There is no timeline for Visual Studio C/C++ at time of writing (it has been +`requested by users `__) + +To be noted that currently clang 19.1 only supports ``#embed`` in .c files, not +C++ ones (the C++ standard has not yet adopted this feature). So embedding +resources must be done in a .c file, which is obviously not a problem since +we can easily export symbols/functions from a .c file to be available by C++. + +New CMake options +----------------- + +Resources will only be embedded if the new ``EMBED_RESOURCE_FILES`` CMake option +is set to ``ON``. This option will default to ``ON`` for static library builds +and if `C23 ``#embed`` is detected to be available. Users might also turn it to ON for +shared library builds. A CMake error is emitted if the option is turned on but +the compiler lacks support for it. + +A complementary CMake option ``USE_ONLY_EMBEDDED_RESOURCE_FILES`` will also +be added. It will default to ``OFF``. When set to ON, GDAL will not try to +locate resource files in the GDAL_DATA directory burnt at build time into libgdal +(``${install_prefix}/share/gdal``), or by the :config:`GDAL_DATA` configuration option. + +Said otherwise, if ``EMBED_RESOURCE_FILES=ON`` but ``USE_ONLY_EMBEDDED_RESOURCE_FILES=OFF``, +GDAL will first try to locate resource files from the file system, and +fallback to the embedded version if not found. + +The resource files will still be installed in ``${install_prefix}/share/gdal``, +unless ``USE_ONLY_EMBEDDED_RESOURCE_FILES`` is set to ON. + +Impacted code +------------- + +- gcore: embedding LICENSE.TXT, and tms_*.json files +- frmts/grib: embedding GRIB2 CSV files +- frmts/hdf5: embedding bag_template.xml +- frmts/nitf: embedding nitf_spec.xml +- frmts/pdf: embedding pdf_composition.xml +- frmts/pds: embedding pds4_template.xml and vicar.json +- ogr/ogrsf_frmts/dgn: embedding seed_2d.dgn and seed_3d.dgn +- ogr/ogrsf_frmts/dxf: embedding header.dxf and leader.dxf +- ogr/ogrsf_frmts/gml: embedding .gfs files and gml_registry.xml +- ogr/ogrsf_frmts/gmlas: embedding gmlasconf.xml +- ogr/ogrsf_frmts/miramon: embedding MM_m_idofic.csv +- ogr/ogrsf_frmts/osm: embedding osm_conf.ini +- ogr/ogrsf_frmts/plscenes: embedding plscenesconf.json +- ogr/ogrsf_frmts/s57: embedding s57*.csv files +- ogr/ogrsf_frmts/sxf: embedding default.rsc +- ogr/ogrsf_frmts/vdv: embedding vdv452.xml + +Considered alternatives +----------------------- + +Including resource files into libraries has been a long-wished feature of C/C++. +Different workarounds have emerged over the years, such as the use of the +``od -x`` utility, GNU ``ld`` linker ``-b`` mode, or CMake-based solutions such +as https://jonathanhamberg.com/post/cmake-file-embedding/ + +We could potentially use the later to address non-C23 capable compilers, but +we have chosen not to do that, for the sake of implementation simplicity. And, +if considering using the CMake trick as the only solution, we should note that +C23 #embed has the potential for better compile time, as demonstrated by clang +implementation. + +Backward compatibility +---------------------- + +Fully backwards compatible. + +C23 is not required, unless EMBED_RESOURCE_FILES is enabled in GDAL. + +Documentation +------------- + +The 2 new CMake variables will be documented. + +Testing +------- + +The existing fedora:rawhide continuous integration target, which has now clang +19.1 available, will be modified to test the effect of the new variables. + +Local builds using GCC 15dev builds of https://jwakely.github.io/pkg-gcc-latest/ +have also be successfully done during the development of the candidate implementation + +Related issues and PRs +---------------------- + +- https://github.com/OSGeo/gdal/issues/10780 + +- `GDAL candidate implementation `__ + +- `PROJ RFC-8 Embedding resource files into libproj `__ + +Voting history +-------------- + ++1 from PSC members JukkaR, JavierJS, KurtS, HowardB and EvenR diff --git a/doc/source/development/rfc/rfc48_geographical_networks_support.rst b/doc/source/development/rfc/rfc48_geographical_networks_support.rst index 0e6bcd2d40fb..32a453bf77cd 100644 --- a/doc/source/development/rfc/rfc48_geographical_networks_support.rst +++ b/doc/source/development/rfc/rfc48_geographical_networks_support.rst @@ -19,7 +19,7 @@ project “GDAL/OGR Geography Network support” into GDAL library. GNM create, manage and analyse networks built over spatial data in GDAL. GSoC project description: -`http://trac.osgeo.org/gdal/wiki/geography_network_support `__ +`http://web.archive.org/web/20240812232429/https://trac.osgeo.org/gdal/wiki/geography_network_support `__ GDAL fork with all changes in trunk: `https://github.com/MikhanGusev/gdal `__ diff --git a/doc/source/development/rfc_process.rst b/doc/source/development/rfc_process.rst new file mode 100644 index 000000000000..6be6e3afdd75 --- /dev/null +++ b/doc/source/development/rfc_process.rst @@ -0,0 +1,69 @@ +.. _rfc_process: + +================================================================================ +Request For Comments (RFC) process for code changes +================================================================================ + +While most bug fixes and small enhancements following the existing logic of code +do not require a RFC and can be done using pull requests, we require contributors +to write a RFC and go through a formal adoption process in the following cases: + +- Anything that could cause backward compatibility issues. +- Adding substantial amounts of new code (see :ref:`rfc-85`) +- Changing inter-subsystem APIs, or objects. +- Anything that might be controversial. + +A good rule of thumb is that if you wonder "does this require a RFC?", the +answer is generally "yes". + +The RFC process is the following one: + +- add a new .rst file in :file:`doc/source/development/rfc` with the RFC text, + and references it in :file:`doc/source/development/rfc/index.rst`, and issue + a pull request. + You can look at https://github.com/OSGeo/gdal/pull/10913 as a potential example + for the expected content. Typical sections are: + + - Title: RFC {XYZ}: {Description of the RFC in a short sentence} + - Author: your name. + - Contact: your email. + - Started: date at which this is started. + - Status: "Draft", when the RFC is started. + - Summary: what the RFC accomplishes in a few sentences. + - Motivation: Paragraph describing why this RFC is needed. + - Technical solution: organized in several sub-paragraph depending on the + complexity of the RFC. You may need to mention new API calls, impacted + files, etc., and other needed details. + - Backward compatibility: API, ABI, and other compatibility concerns. + - Performance impacts. + - Documentation: how this will be documented. + - Testing: how this will be tested. + - Related issues and PRs: points at potential existing tickets about the topic, + and pull request with a candidate implementation + - Voting history: "TBD" (to be defined), when the RFC is started + +- Send an email to the :ref:`gdal-dev mailing list ` with a title like: + "Call for discussion on RFC {XYZ}: {Description of the RFC in a short sentence}" + where you point to the pull request. You may get feedback both in the pull + request or in the mailing list. + +- Wait for feedback (give readers at least one week, or more if holiday season). + If it seems positive and reasonable consensus can be reached, you can start + working on a candidate implementation, and issue a pull request for it, + separate for the pull request with the RFC text. + Reference this candidate implementation pull request in the "Related issues + and PRs" section of the RFC text. + +- Once your candidate implementation is representative enough, and you and other + contributors can have a good confidence that the RFC can be implemented in the + way it has been described, send an email to the gdal-dev mailing list with + a title like "Motion: adopt RFC {XYZ}: {Description of the RFC in a short sentence}" + where you point to the pull request. + All subscribers can vote, but only votes from members of the GDAL Project + Steering Committee are binding. The voting rules are covered by :ref:`rfc-1`. + +- Once the RFC is approved, finish your candidate implementation if not already + finished, and wait for the review process and for it to be merged. + +- Update the Status to "Adopted, implemented" and Voting history sections of the + RFC text. diff --git a/doc/source/download.rst b/doc/source/download.rst index 7fb82cf4bd68..e7203e7977dd 100644 --- a/doc/source/download.rst +++ b/doc/source/download.rst @@ -18,16 +18,22 @@ Source Code Current Release ............... -* **2024-08-16** `gdal-3.9.2.tar.gz`_ `3.9.2 Release Notes`_ (`3.9.2 md5`_) +* **2024-11-01** `gdal-3.10.0.tar.gz`_ `3.10.0 Release Notes`_ (`3.10.0 md5`_) -.. _`3.9.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.9.2/NEWS.md -.. _`gdal-3.9.2.tar.gz`: https://github.com/OSGeo/gdal/releases/download/v3.9.2/gdal-3.9.2.tar.gz -.. _`3.9.2 md5`: https://github.com/OSGeo/gdal/releases/download/v3.9.2/gdal-3.9.2.tar.gz.md5 +.. _`3.10.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.10.0/NEWS.md +.. _`gdal-3.10.0.tar.gz`: https://github.com/OSGeo/gdal/releases/download/v3.10.0/gdal-3.10.0.tar.gz +.. _`3.10.0 md5`: https://github.com/OSGeo/gdal/releases/download/v3.10.0/gdal-3.10.0.tar.gz.md5 Past Releases ............. -Links to :ref:`download_past` are also available. +.. only:: html + + Links to :ref:`download_past` are also available. + +.. only:: not html + + Links to `past releases `__ are also available. .. _source: @@ -97,6 +103,25 @@ GDAL packages are available on `Homebrew`_. .. _`Homebrew`: https://formulae.brew.sh/formula/gdal +Android +....... + +GDAL can be installed using :ref:`vcpkg`. You may also refer to `vcpkg Android support `__ for general instructions. + +For example to install default configuration for the ``arm64-android`` target: + +.. code-block:: shell + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh # ./bootstrap-vcpkg.bat for Windows + ./vcpkg integrate install + export ANDROID_NDK_HOME=/path/to/android_ndk_home # to adapt + ./vcpkg search gdal --featurepackages # list optional features + ./vcpkg install gdal:arm64-android # install with default configuration + ./vcpkg install gdal[poppler,netcdf]:arm64-android # install with Poppler and netdf support + + Cross-Platform Package Managers ............................... @@ -125,11 +150,13 @@ GDAL is available as several subpackages: - ``gdal``: Python bindings and Python utilities (depends on libgdal-core) - ``libgdal``: meta-package gathering all below libgdal-* packages (except libgdal-arrow-parquet) - ``libgdal-arrow-parquet``: :ref:`vector.arrow` and :ref:`vector.parquet` drivers as a plugin (depends on libgdal-core) +- ``libgdal-avif``: :ref:`raster.avif` driver as a plugin (depends on libgdal-core, available since GDAL 3.10.0) - ``libgdal-core``: core library and C++ utilities, with a number of builtin drivers (available since GDAL 3.9.1) - ``libgdal-fits``: :ref:`raster.fits` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) - ``libgdal-grib``: :ref:`raster.grib` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) - ``libgdal-hdf4``: :ref:`raster.hdf4` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) - ``libgdal-hdf5``: :ref:`raster.hdf5` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) +- ``libgdal-heif``: :ref:`raster.heif` driver as a plugin (depends on libgdal-core, available since GDAL 3.10.0) - ``libgdal-jp2openjpeg``: :ref:`raster.jp2openjpeg` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) - ``libgdal-kea``: :ref:`raster.kea` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) - ``libgdal-netcdf``: :ref:`raster.netcdf` driver as a plugin (depends on libgdal-core, available since GDAL 3.9.1) @@ -193,13 +220,15 @@ vcpkg The GDAL port in the `vcpkg `__ dependency manager is kept up to date by Microsoft team members and community contributors. You can download and install GDAL using the vcpkg as follows: -:: +.. code-block:: shell git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh # ./bootstrap-vcpkg.bat for Windows ./vcpkg integrate install - ./vcpkg install gdal + ./vcpkg search gdal --featurepackages # list optional features + ./vcpkg install gdal # install with default configuration + ./vcpkg install gdal[poppler,netcdf] # install with Poppler and netdf support If the version is out of date, please `create an issue or pull request `__ on the vcpkg repository. diff --git a/doc/source/download_past.rst b/doc/source/download_past.rst index 340924f953a1..afff6413df04 100644 --- a/doc/source/download_past.rst +++ b/doc/source/download_past.rst @@ -5,6 +5,18 @@ Past Releases ============= +* **2024-10-14** `gdal-3.9.3.tar.gz`_ `3.9.3 Release Notes`_ (`3.9.3 md5`_) + +.. _`3.9.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.9.3/NEWS.md +.. _`gdal-3.9.3.tar.gz`: https://github.com/OSGeo/gdal/releases/download/v3.9.3/gdal-3.9.3.tar.gz +.. _`3.9.3 md5`: https://github.com/OSGeo/gdal/releases/download/v3.9.3/gdal-3.9.3.tar.gz.md5 + +* **2024-08-16** `gdal-3.9.2.tar.gz`_ `3.9.2 Release Notes`_ (`3.9.2 md5`_) + +.. _`3.9.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.9.2/NEWS.md +.. _`gdal-3.9.2.tar.gz`: https://github.com/OSGeo/gdal/releases/download/v3.9.2/gdal-3.9.2.tar.gz +.. _`3.9.2 md5`: https://github.com/OSGeo/gdal/releases/download/v3.9.2/gdal-3.9.2.tar.gz.md5 + * **2024-06-26** `gdal-3.9.1.tar.gz`_ `3.9.1 Release Notes`_ (`3.9.1 md5`_) .. _`3.9.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.9.1/NEWS.md @@ -277,279 +289,279 @@ Past Releases .. _`2.4.2 md5`: https://download.osgeo.org/gdal/2.4.2/gdal-2.4.2.tar.gz.md5 -* **2019-05** `gdal-3.0.0.tar.gz`_ `3.0.0 Release Notes`_ (`3.0.0 md5`)_ +* **2019-05** `gdal-3.0.0.tar.gz`_ `3.0.0 Release Notes`_ (`3.0.0 md5`_) .. _`gdal-3.0.0.tar.gz`: http://download.osgeo.org/gdal/3.0.0/gdal-3.0.0.tar.gz .. _`3.0.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.0.0/gdal/NEWS .. _`3.0.0 md5`: http://download.osgeo.org/gdal/3.0.0/gdal-3.0.0.tar.gz.md5 -* **2019-03** `gdal-2.4.1.tar.gz`_ `2.4.1 Release Notes`_ (`2.4.1 md5`)_ +* **2019-03** `gdal-2.4.1.tar.gz`_ `2.4.1 Release Notes`_ (`2.4.1 md5`_) .. _`gdal-2.4.1.tar.gz`: http://download.osgeo.org/gdal/2.4.1/gdal-2.4.1.tar.gz .. _`2.4.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.4.1/gdal/NEWS .. _`2.4.1 md5`: http://download.osgeo.org/gdal/2.4.1/gdal-2.4.1.tar.gz.md5 -* **2018-12** `gdal-2.4.0.tar.gz`_ `2.4.0 Release Notes`_ (`2.4.0 md5`)_ +* **2018-12** `gdal-2.4.0.tar.gz`_ `2.4.0 Release Notes`_ (`2.4.0 md5`_) .. _`gdal-2.4.0.tar.gz`: http://download.osgeo.org/gdal/2.4.0/gdal-2.4.0.tar.gz .. _`2.4.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.4.0/gdal/NEWS .. _`2.4.0 md5`: http://download.osgeo.org/gdal/2.4.0/gdal-2.4.0.tar.gz.md5 -* **2019-05** `gdal-3.0.0.tar.gz`_ `3.0.0 Release Notes`_ (`3.0.0 md5`)_ +* **2019-05** `gdal-3.0.0.tar.gz`_ `3.0.0 Release Notes`_ (`3.0.0 md5`_) .. _`gdal-3.0.0.tar.gz`: http://download.osgeo.org/gdal/3.0.0/gdal-3.0.0.tar.gz .. _`3.0.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v3.0.0/gdal/NEWS .. _`3.0.0 md5`: http://download.osgeo.org/gdal/3.0.0/gdal-3.0.0.tar.gz.md5 -* **2019-03** `gdal-2.4.1.tar.gz`_ `2.4.1 Release Notes`_ (`2.4.1 md5`)_ +* **2019-03** `gdal-2.4.1.tar.gz`_ `2.4.1 Release Notes`_ (`2.4.1 md5`_) .. _`gdal-2.4.1.tar.gz`: http://download.osgeo.org/gdal/2.4.1/gdal-2.4.1.tar.gz .. _`2.4.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.4.1/gdal/NEWS .. _`2.4.1 md5`: http://download.osgeo.org/gdal/2.4.1/gdal-2.4.1.tar.gz.md5 -* **2018-12** `gdal-2.4.0.tar.gz`_ `2.4.0 Release Notes`_ (`2.4.0 md5`)_ +* **2018-12** `gdal-2.4.0.tar.gz`_ `2.4.0 Release Notes`_ (`2.4.0 md5`_) .. _`gdal-2.4.0.tar.gz`: http://download.osgeo.org/gdal/2.4.0/gdal-2.4.0.tar.gz .. _`2.4.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.4.0/gdal/NEWS .. _`2.4.0 md5`: http://download.osgeo.org/gdal/2.4.0/gdal-2.4.0.tar.gz.md5 -* **2018-12** `gdal-2.3.3.tar.gz`_ `2.3.3 Release Notes`_ (`2.3.3 md5`)_ +* **2018-12** `gdal-2.3.3.tar.gz`_ `2.3.3 Release Notes`_ (`2.3.3 md5`_) .. _`gdal-2.3.3.tar.gz`: http://download.osgeo.org/gdal/2.3.3/gdal-2.3.3.tar.gz .. _`2.3.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.3.3/gdal/NEWS .. _`2.3.3 md5`: http://download.osgeo.org/gdal/2.3.3/gdal-2.3.3.tar.gz.md5 -* **2018-09** `gdal-2.3.2.tar.gz`_ `2.3.2 Release Notes`_ (`2.3.2 md5`)_ +* **2018-09** `gdal-2.3.2.tar.gz`_ `2.3.2 Release Notes`_ (`2.3.2 md5`_) .. _`gdal-2.3.2.tar.gz`: http://download.osgeo.org/gdal/2.3.2/gdal-2.3.2.tar.gz .. _`2.3.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.3.2/gdal/NEWS .. _`2.3.2 md5`: http://download.osgeo.org/gdal/2.3.2/gdal-2.3.2.tar.gz.md5 -* **2018-06** `gdal-2.3.1.tar.gz`_ `2.3.1 Release Notes`_ (`2.3.1 md5`)_ +* **2018-06** `gdal-2.3.1.tar.gz`_ `2.3.1 Release Notes`_ (`2.3.1 md5`_) .. _`gdal-2.3.1.tar.gz`: http://download.osgeo.org/gdal/2.3.1/gdal-2.3.1.tar.gz .. _`2.3.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.3.1/gdal/NEWS .. _`2.3.1 md5`: http://download.osgeo.org/gdal/2.3.1/gdal-2.3.1.tar.gz.md5 -* **2018-05** `gdal-2.3.0.tar.gz`_ `2.3.0 Release Notes`_ (`2.3.0 md5`)_ +* **2018-05** `gdal-2.3.0.tar.gz`_ `2.3.0 Release Notes`_ (`2.3.0 md5`_) .. _`gdal-2.3.0.tar.gz`: http://download.osgeo.org/gdal/2.3.0/gdal-2.3.0.tar.gz .. _`2.3.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.3.0/gdal/NEWS .. _`2.3.0 md5`: http://download.osgeo.org/gdal/2.3.0/gdal-2.3.0.tar.gz.md5 -* **2018-03** `gdal-2.2.4.tar.gz`_ `2.2.4 Release Notes`_ (`2.2.4 md5`)_ +* **2018-03** `gdal-2.2.4.tar.gz`_ `2.2.4 Release Notes`_ (`2.2.4 md5`_) .. _`gdal-2.2.4.tar.gz`: http://download.osgeo.org/gdal/2.2.4/gdal-2.2.4.tar.gz .. _`2.2.4 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.2.4/gdal/NEWS .. _`2.2.4 md5`: http://download.osgeo.org/gdal/2.2.4/gdal-2.2.4.tar.gz.md5 -* **2017-11** `gdal-2.2.3.tar.gz`_ `2.2.3 Release Notes`_ (`2.2.3 md5`)_ +* **2017-11** `gdal-2.2.3.tar.gz`_ `2.2.3 Release Notes`_ (`2.2.3 md5`_) .. _`gdal-2.2.3.tar.gz`: http://download.osgeo.org/gdal/2.2.3/gdal-2.2.3.tar.gz .. _`2.2.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.2.3/gdal/NEWS .. _`2.2.3 md5`: http://download.osgeo.org/gdal/2.2.3/gdal-2.2.3.tar.gz.md5 -* **2017-09** `gdal-2.2.2.tar.gz`_ `2.2.2 Release Notes`_ (`2.2.2 md5`)_ +* **2017-09** `gdal-2.2.2.tar.gz`_ `2.2.2 Release Notes`_ (`2.2.2 md5`_) .. _`gdal-2.2.2.tar.gz`: http://download.osgeo.org/gdal/2.2.2/gdal-2.2.2.tar.gz .. _`2.2.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.2.2/gdal/NEWS .. _`2.2.2 md5`: http://download.osgeo.org/gdal/2.2.2/gdal-2.2.2.tar.gz.md5 -* **2017-06** `gdal-2.2.1.tar.gz`_ `2.2.1 Release Notes`_ (`2.2.1 md5`)_ +* **2017-06** `gdal-2.2.1.tar.gz`_ `2.2.1 Release Notes`_ (`2.2.1 md5`_) .. _`gdal-2.2.1.tar.gz`: http://download.osgeo.org/gdal/2.2.1/gdal-2.2.1.tar.gz .. _`2.2.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.2.1/gdal/NEWS .. _`2.2.1 md5`: http://download.osgeo.org/gdal/2.2.1/gdal-2.2.1.tar.gz.md5 -* **2017-06** `gdal-2.1.4.tar.gz`_ `2.1.4 Release Notes`_ (`2.1.4 md5`)_ +* **2017-06** `gdal-2.1.4.tar.gz`_ `2.1.4 Release Notes`_ (`2.1.4 md5`_) .. _`gdal-2.1.4.tar.gz`: http://download.osgeo.org/gdal/2.1.4/gdal-2.1.4.tar.gz .. _`2.1.4 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.1.4/gdal/NEWS .. _`2.1.4 md5`: http://download.osgeo.org/gdal/2.1.4/gdal-2.1.4.tar.gz.md5 -* **2017-04** `gdal-2.2.0.tar.gz`_ `2.2.0 Release Notes`_ (`2.2.0 md5`)_ +* **2017-04** `gdal-2.2.0.tar.gz`_ `2.2.0 Release Notes`_ (`2.2.0 md5`_) .. _`gdal-2.2.0.tar.gz`: http://download.osgeo.org/gdal/2.2.0/gdal-2.2.0.tar.gz .. _`2.2.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.2.0/gdal/NEWS .. _`2.2.0 md5`: http://download.osgeo.org/gdal/2.2.0/gdal-2.2.0.tar.gz.md5 -* **2017-01** `gdal-2.1.3.tar.gz`_ `2.1.3 Release Notes`_ (`2.1.3 md5`)_ +* **2017-01** `gdal-2.1.3.tar.gz`_ `2.1.3 Release Notes`_ (`2.1.3 md5`_) .. _`gdal-2.1.3.tar.gz`: http://download.osgeo.org/gdal/2.1.3/gdal-2.1.3.tar.gz .. _`2.1.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.1.3/gdal/NEWS .. _`2.1.3 md5`: http://download.osgeo.org/gdal/2.1.3/gdal-2.1.3.tar.gz.md5 -* **2016-10** `gdal-2.1.2.tar.gz`_ `2.1.2 Release Notes`_ (`2.1.2 md5`)_ +* **2016-10** `gdal-2.1.2.tar.gz`_ `2.1.2 Release Notes`_ (`2.1.2 md5`_) .. _`gdal-2.1.2.tar.gz`: http://download.osgeo.org/gdal/2.1.2/gdal-2.1.2.tar.gz .. _`2.1.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.1.2/gdal/NEWS .. _`2.1.2 md5`: http://download.osgeo.org/gdal/2.1.2/gdal-2.1.2.tar.gz.md5 -* **2016-07** `gdal-2.1.1.tar.gz`_ `2.1.1 Release Notes`_ (`2.1.1 md5`)_ +* **2016-07** `gdal-2.1.1.tar.gz`_ `2.1.1 Release Notes`_ (`2.1.1 md5`_) .. _`gdal-2.1.1.tar.gz`: http://download.osgeo.org/gdal/2.1.1/gdal-2.1.1.tar.gz .. _`2.1.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.1.1/gdal/NEWS .. _`2.1.1 md5`: http://download.osgeo.org/gdal/2.1.1/gdal-2.1.1.tar.gz.md5 -* **2016-07** `gdal-2.0.3.tar.gz`_ `2.0.3 Release Notes`_ (`2.0.3 md5`)_ +* **2016-07** `gdal-2.0.3.tar.gz`_ `2.0.3 Release Notes`_ (`2.0.3 md5`_) .. _`gdal-2.0.3.tar.gz`: http://download.osgeo.org/gdal/2.0.3/gdal-2.0.3.tar.gz .. _`2.0.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.0.3/gdal/NEWS .. _`2.0.3 md5`: http://download.osgeo.org/gdal/2.0.3/gdal-2.0.3.tar.gz.md5 -* **2016-07** `gdal-1.11.5.tar.gz`_ `1.11.5 Release Notes`_ (`1.11.5 md5`)_ +* **2016-07** `gdal-1.11.5.tar.gz`_ `1.11.5 Release Notes`_ (`1.11.5 md5`_) .. _`gdal-1.11.5.tar.gz`: http://download.osgeo.org/gdal/1.11.5/gdal-1.11.5.tar.gz .. _`1.11.5 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.5/gdal/NEWS .. _`1.11.5 md5`: http://download.osgeo.org/gdal/1.11.5/gdal-1.11.5.tar.gz.md5 -* **2016-04** `gdal-2.1.0.tar.gz`_ `2.1.0 Release Notes`_ (`2.1.0 md5`)_ +* **2016-04** `gdal-2.1.0.tar.gz`_ `2.1.0 Release Notes`_ (`2.1.0 md5`_) .. _`gdal-2.1.0.tar.gz`: http://download.osgeo.org/gdal/2.1.0/gdal-2.1.0.tar.gz .. _`2.1.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.1.0/gdal/NEWS .. _`2.1.0 md5`: http://download.osgeo.org/gdal/2.1.0/gdal-2.1.0.tar.gz.md5 -* **2016-01** `gdal-2.0.2.tar.gz`_ `2.0.2 Release Notes`_ (`2.0.2 md5`)_ +* **2016-01** `gdal-2.0.2.tar.gz`_ `2.0.2 Release Notes`_ (`2.0.2 md5`_) .. _`gdal-2.0.2.tar.gz`: http://download.osgeo.org/gdal/2.0.2/gdal-2.0.2.tar.gz .. _`2.0.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.0.2/gdal/NEWS .. _`2.0.2 md5`: http://download.osgeo.org/gdal/2.0.2/gdal-2.0.2.tar.gz.md5 -* **2016-01** `gdal-1.11.4.tar.gz`_ `1.11.4 Release Notes`_ (`1.11.4 md5`)_ +* **2016-01** `gdal-1.11.4.tar.gz`_ `1.11.4 Release Notes`_ (`1.11.4 md5`_) .. _`gdal-1.11.4.tar.gz`: http://download.osgeo.org/gdal/1.11.4/gdal-1.11.4.tar.gz .. _`1.11.4 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.4/gdal/NEWS .. _`1.11.4 md5`: http://download.osgeo.org/gdal/1.11.4/gdal-1.11.4.tar.gz.md5 -* **2015-09** `gdal-2.0.1.tar.gz`_ `2.0.1 Release Notes`_ (`2.0.1 md5`)_ +* **2015-09** `gdal-2.0.1.tar.gz`_ `2.0.1 Release Notes`_ (`2.0.1 md5`_) .. _`gdal-2.0.1.tar.gz`: http://download.osgeo.org/gdal/2.0.1/gdal-2.0.1.tar.gz .. _`2.0.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.0.1/gdal/NEWS .. _`2.0.1 md5`: http://download.osgeo.org/gdal/2.0.1/gdal-2.0.1.tar.gz.md5 -* **2015-09** `gdal-1.11.3.tar.gz`_ `1.11.3 Release Notes`_ (`1.11.3 md5`)_ +* **2015-09** `gdal-1.11.3.tar.gz`_ `1.11.3 Release Notes`_ (`1.11.3 md5`_) .. _`gdal-1.11.3.tar.gz`: http://download.osgeo.org/gdal/1.11.3/gdal-1.11.3.tar.gz .. _`1.11.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.3/gdal/NEWS .. _`1.11.3 md5`: http://download.osgeo.org/gdal/1.11.3/gdal-1.11.3.tar.gz.md5 -* **2015-06** `gdal-2.0.0.tar.gz`_ `2.0.0 Release Notes`_ (`2.0.0 md5`)_ +* **2015-06** `gdal-2.0.0.tar.gz`_ `2.0.0 Release Notes`_ (`2.0.0 md5`_) .. _`gdal-2.0.0.tar.gz`: http://download.osgeo.org/gdal/2.0.0/gdal-2.0.0.tar.gz .. _`2.0.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v2.0.0/gdal/NEWS .. _`2.0.0 md5`: http://download.osgeo.org/gdal/2.0.0/gdal-2.0.0.tar.gz.md5 -* **2015-02** `gdal-1.11.2.tar.gz`_ `1.11.2 Release Notes`_ (`1.11.2 md5`)_ +* **2015-02** `gdal-1.11.2.tar.gz`_ `1.11.2 Release Notes`_ (`1.11.2 md5`_) .. _`gdal-1.11.2.tar.gz`: http://download.osgeo.org/gdal/1.11.2/gdal-1.11.2.tar.gz .. _`1.11.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.2/gdal/NEWS .. _`1.11.2 md5`: http://download.osgeo.org/gdal/1.11.2/gdal-1.11.2.tar.gz.md5 -* **2014-09** `gdal-1.11.1.tar.gz`_ `1.11.1 Release Notes`_ (`1.11.1 md5`)_ +* **2014-09** `gdal-1.11.1.tar.gz`_ `1.11.1 Release Notes`_ (`1.11.1 md5`_) .. _`gdal-1.11.1.tar.gz`: http://download.osgeo.org/gdal/1.11.1/gdal-1.11.1.tar.gz .. _`1.11.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.1/gdal/NEWS .. _`1.11.1 md5`: http://download.osgeo.org/gdal/1.11.1/gdal-1.11.1.tar.gz.md5 -* **2014-04** `gdal-1.11.0.tar.gz`_ `1.11.0 Release Notes`_ (`1.11.0 md5`)_ +* **2014-04** `gdal-1.11.0.tar.gz`_ `1.11.0 Release Notes`_ (`1.11.0 md5`_) .. _`gdal-1.11.0.tar.gz`: http://download.osgeo.org/gdal/1.11.0/gdal-1.11.0.tar.gz .. _`1.11.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.11.0/gdal/NEWS .. _`1.11.0 md5`: http://download.osgeo.org/gdal/1.11.0/gdal-1.11.0.tar.gz.md5 -* **2013-08** `gdal-1.10.1.tar.gz`_ `1.10.1 Release Notes`_ (`1.10.1 md5`)_ +* **2013-08** `gdal-1.10.1.tar.gz`_ `1.10.1 Release Notes`_ (`1.10.1 md5`_) .. _`gdal-1.10.1.tar.gz`: http://download.osgeo.org/gdal/1.10.1/gdal-1.10.1.tar.gz .. _`1.10.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.10.1/gdal/NEWS .. _`1.10.1 md5`: http://download.osgeo.org/gdal/1.10.1/gdal-1.10.1.tar.gz.md5 -* **2013-04** `gdal-1.10.0.tar.gz`_ `1.10.0 Release Notes`_ (`1.10.0 md5`)_ +* **2013-04** `gdal-1.10.0.tar.gz`_ `1.10.0 Release Notes`_ (`1.10.0 md5`_) .. _`gdal-1.10.0.tar.gz`: http://download.osgeo.org/gdal/1.10.0/gdal-1.10.0.tar.gz .. _`1.10.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.10.0/gdal/NEWS .. _`1.10.0 md5`: http://download.osgeo.org/gdal/1.10.0/gdal-1.10.0.tar.gz.md5 -* **2012-10** `gdal-1.9.2.tar.gz`_ `1.9.2 Release Notes`_ (`1.9.2 md5`)_ +* **2012-10** `gdal-1.9.2.tar.gz`_ `1.9.2 Release Notes`_ (`1.9.2 md5`_) .. _`gdal-1.9.2.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.2.tar.gz .. _`1.9.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.9.2/gdal/NEWS .. _`1.9.2 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.2.tar.gz.md5 -* **2012-05** `gdal-1.9.1.tar.gz`_ `1.9.1 Release Notes`_ (`1.9.1 md5`)_ +* **2012-05** `gdal-1.9.1.tar.gz`_ `1.9.1 Release Notes`_ (`1.9.1 md5`_) .. _`gdal-1.9.1.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.1.tar.gz .. _`1.9.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.9.1/gdal/NEWS .. _`1.9.1 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.1.tar.gz.md5 -* **2011-12** `gdal-1.9.0.tar.gz`_ `1.9.0 Release Notes`_ (`1.9.0 md5`)_ +* **2011-12** `gdal-1.9.0.tar.gz`_ `1.9.0 Release Notes`_ (`1.9.0 md5`_) .. _`gdal-1.9.0.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.0.tar.gz .. _`1.9.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.9.0/gdal/NEWS .. _`1.9.0 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.9.0.tar.gz.md5 -* **2011-07** `gdal-1.8.1.tar.gz`_ `1.8.1 Release Notes`_ (`1.8.1 md5`)_ +* **2011-07** `gdal-1.8.1.tar.gz`_ `1.8.1 Release Notes`_ (`1.8.1 md5`_) .. _`gdal-1.8.1.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.8.1.tar.gz .. _`1.8.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.8.1/gdal/NEWS .. _`1.8.1 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.8.1.tar.gz.md5 -* **2011-01** `gdal-1.8.0.tar.gz`_ `1.8.0 Release Notes`_ (`1.8.0 md5`)_ +* **2011-01** `gdal-1.8.0.tar.gz`_ `1.8.0 Release Notes`_ (`1.8.0 md5`_) .. _`gdal-1.8.0.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.8.0.tar.gz .. _`1.8.0 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.8.0/gdal/NEWS .. _`1.8.0 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.8.0.tar.gz.md5 -* **2010-11** `gdal-1.7.3.tar.gz`_ `1.7.3 Release Notes`_ (`1.7.3 md5`)_ +* **2010-11** `gdal-1.7.3.tar.gz`_ `1.7.3 Release Notes`_ (`1.7.3 md5`_) .. _`gdal-1.7.3.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.7.3.tar.gz .. _`1.7.3 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.7.3/gdal/NEWS .. _`1.7.3 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.7.3.tar.gz.md5 -* **2010-04** `gdal-1.7.2.tar.gz`_ `1.7.2 Release Notes`_ (`1.7.2 md5`)_ +* **2010-04** `gdal-1.7.2.tar.gz`_ `1.7.2 Release Notes`_ (`1.7.2 md5`_) .. _`gdal-1.7.2.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.7.2.tar.gz .. _`1.7.2 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.7.2/gdal/NEWS .. _`1.7.2 md5`: http://download.osgeo.org/gdal/old_releases/gdal-1.7.2.tar.gz.md5 -* **2010-02** `gdal-1.7.1.tar.gz`_ `1.7.1 Release Notes`_ (`1.7.1 md5`)_ +* **2010-02** `gdal-1.7.1.tar.gz`_ `1.7.1 Release Notes`_ (`1.7.1 md5`_) .. _`gdal-1.7.1.tar.gz`: http://download.osgeo.org/gdal/old_releases/gdal-1.7.1.tar.gz .. _`1.7.1 Release Notes`: https://github.com/OSGeo/gdal/blob/v1.7.1/gdal/NEWS diff --git a/doc/source/drivers/raster/cog.rst b/doc/source/drivers/raster/cog.rst index 381cecdc9e7a..c46bac1f5703 100644 --- a/doc/source/drivers/raster/cog.rst +++ b/doc/source/drivers/raster/cog.rst @@ -53,9 +53,7 @@ General creation options * ``JPEG`` should generally only be used with Byte data (8 bit per channel). But if GDAL is built with internal libtiff and libjpeg, it is possible to read and write TIFF files with 12bit JPEG compressed TIFF - files (seen as UInt16 bands with NBITS=12). See the `"8 and 12 bit - JPEG in TIFF" `__ wiki - page for more details. + files (seen as UInt16 bands with NBITS=12). For the COG driver, JPEG compression for 3 or 4-band images automatically selects the PHOTOMETRIC=YCBCR colorspace with a 4:2:2 subsampling of the Y,Cb,Cr components. @@ -127,7 +125,7 @@ General creation options The higher, the smaller file and slower compression time. - .. co:: JXL_DISTANCE - :choices: 0.1-15 + :choices: 0.01-25 :default: 1.0 Distance level for lossy JPEG-XL compression. @@ -139,7 +137,7 @@ General creation options The recommended range is [0.5,3]. - .. co:: JXL_ALPHA_DISTANCE - :choices: -1, 0, 0.1-15 + :choices: -1, 0, 0.01-25 :default: -1 :since: 3.7 @@ -612,8 +610,6 @@ See Also -------- - :ref:`raster.gtiff` driver -- `How to generate and read cloud optimized GeoTIFF - files `__ (before GDAL 3.1) - If your source dataset is an internally tiled geotiff with the desired georeferencing and compression, using `cogger `__ (possibly along with gdaladdo to create overviews) will be much faster than the COG driver. diff --git a/doc/source/drivers/raster/ecw.rst b/doc/source/drivers/raster/ecw.rst index f30d728f1ea4..add3aa839c5a 100644 --- a/doc/source/drivers/raster/ecw.rst +++ b/doc/source/drivers/raster/ecw.rst @@ -327,4 +327,3 @@ See Also `Hexagon Geospatial public forum `__ - Community contributed `patches `__ to apply to ECW SDK 3.3 sources -- `GDAL ECW Build Hints `__ diff --git a/doc/source/drivers/raster/eedai.rst b/doc/source/drivers/raster/eedai.rst index 7ce85962c03f..61337ed0d6c1 100644 --- a/doc/source/drivers/raster/eedai.rst +++ b/doc/source/drivers/raster/eedai.rst @@ -60,6 +60,12 @@ The following open options are available : Size of a GDAL block, which is the minimum unit to query pixels. +- .. oo:: VSI_PATH_FOR_AUTH + :since: 3.10 + + /vsigs/... path onto which a GOOGLE_APPLICATION_CREDENTIALS path specific + option is set + Authentication methods ---------------------- @@ -68,7 +74,9 @@ The following authentication methods can be used: - Authentication Bearer header passed through the :config:`EEDA_BEARER` or :config:`EEDA_BEARER_FILE` configuration options. - Service account private key file, through the - :config:`GOOGLE_APPLICATION_CREDENTIALS` configuration option. + :config:`GOOGLE_APPLICATION_CREDENTIALS` configuration option, or set + as a path-specific option whose value is set in the VSI_PATH_FOR_AUTH + open option. - OAuth2 Service Account authentication through the :config:`EEDA_PRIVATE_KEY`/ :config:`EEDA_PRIVATE_KEY_FILE` + :config:`EEDA_CLIENT_EMAIL` configuration options. - Finally if none of the above method succeeds, the code will check if diff --git a/doc/source/drivers/raster/gti.rst b/doc/source/drivers/raster/gti.rst index f719bea62b24..f44f0b359b12 100644 --- a/doc/source/drivers/raster/gti.rst +++ b/doc/source/drivers/raster/gti.rst @@ -42,7 +42,8 @@ driver with the following main differences: * Contrary to the VRT driver, the GTI driver does not enable to alter characteristics of referenced tiles, such as their georeferencing, nodata value, etc. If such behavior is desired, the tiles must be for example wrapped - individually in a VRT file before being referenced in the GTI index. + individually in a VRT file (or `vrt://` connection string) before being referenced + in the GTI index. Connection strings ------------------ @@ -79,7 +80,7 @@ STAC GeoParquet support .. versionadded:: 3.10 The driver can support `STAC GeoParquet catalogs `_, -provided GDAL is build with :ref:`vector.parquet` support. +provided GDAL is built with :ref:`vector.parquet` support. It can make use of fields ``proj:epsg`` and ``proj:transform`` from the `Projection Extension Specification `_, to correctly infer the appropriate projection and resolution. diff --git a/doc/source/drivers/raster/gtiff.rst b/doc/source/drivers/raster/gtiff.rst index 0381a5b8f0e0..f86a9fef8546 100644 --- a/doc/source/drivers/raster/gtiff.rst +++ b/doc/source/drivers/raster/gtiff.rst @@ -384,9 +384,6 @@ The TIFF format only supports R,G,B components for palettes / color tables. Thus on writing the alpha information will be silently discarded. -You may want to read hints to `generate and read cloud optimized GeoTIFF -files `__ - Creation Options ~~~~~~~~~~~~~~~~ @@ -488,9 +485,10 @@ This driver supports the following creation options: * ``LERC_ZSTD`` is available when ``LERC`` and ``ZSTD`` are available. * ``JXL`` is for JPEG-XL, and is only available when using internal libtiff and building GDAL against - https://github.com/libjxl/libjxl . Supported data types are ``Byte``, ``UInt16`` and ``Float32`` only. - For GDAL < 3.6.0, JXL compression may only be used alongside ``INTERLEAVE=PIXEL`` (the default) on - datasets with 4 bands or less. + https://github.com/libjxl/libjxl . It is recommended to use JXL compression with the ``TILED=YES`` creation + option and block size of 256x256, 512x512, or 1024x1024 pixels. Supported data types are ``Byte``, + ``UInt16`` and ``Float32`` only. For GDAL < 3.6.0, JXL compression may only be used alongside + ``INTERLEAVE=PIXEL`` (the default) on datasets with 4 bands or less. * ``NONE`` is the default. @@ -637,7 +635,7 @@ This driver supports the following creation options: The higher, the smaller file and slower compression time. - .. co:: JXL_DISTANCE - :choices: [0.1-15] + :choices: [0.01-25] :default: 1.0 Distance level for lossy JPEG-XL compression. @@ -649,7 +647,7 @@ This driver supports the following creation options: The recommended range is [0.5,3]. - .. co:: JXL_ALPHA_DISTANCE - :choices: -1,0,[0.1-15] + :choices: -1,0,[0.01-25] :default: -1 :since: 3.7 diff --git a/doc/source/drivers/raster/heif.rst b/doc/source/drivers/raster/heif.rst index 803e281ac8cd..a70e9e0a83c6 100644 --- a/doc/source/drivers/raster/heif.rst +++ b/doc/source/drivers/raster/heif.rst @@ -1,7 +1,7 @@ .. _raster.heif: ================================================================================ -HEIF / HEIC -- ISO/IEC 23008-12:2017 High Efficiency Image File Format +HEIF / HEIC -- ISO/IEC 23008-12 High Efficiency Image File Format ================================================================================ .. versionadded:: 3.2 @@ -18,11 +18,14 @@ iOS 11 can generate such files. libheif 1.4 or later is needed to support images with more than 8-bits per channel. +Later versions of libheif may also support one or more of AVIF (AV1 in HEIF), JPEG, JPEG 2000 and +uncompressed images depending on compile-time options. + The driver can read EXIF metadata (exposed in the ``EXIF`` metadata domain) and XMP metadata (exposed in the ``xml:XMP`` metadata domain) The driver will expose the thumbnail as an overview (when its number of bands -matches the one of the full resolution image) +matches the number of bands in the full resolution image). If a file contains several top-level images, they will be exposed as GDAL subdatasets. @@ -41,6 +44,8 @@ Driver capabilities .. supports_virtualio:: if libheif >= 1.4 +.. supports_createcopy:: + Built hints on Windows ---------------------- diff --git a/doc/source/drivers/raster/index.rst b/doc/source/drivers/raster/index.rst index 7f2955a11135..0e511f99951f 100644 --- a/doc/source/drivers/raster/index.rst +++ b/doc/source/drivers/raster/index.rst @@ -96,7 +96,6 @@ Raster drivers jdem jp2ecw jp2kak - jp2lura jp2mrsid jp2openjpeg jpeg @@ -148,6 +147,7 @@ Raster drivers rasterlite2 r rdb + rcm rik rmf roi_pac @@ -164,6 +164,7 @@ Raster drivers sentinel2 sgi sigdem + snap_tiff snodas srp srtmhgt diff --git a/doc/source/drivers/raster/jp2ecw.rst b/doc/source/drivers/raster/jp2ecw.rst index fe1df5c8d7d1..3a4c59172e88 100644 --- a/doc/source/drivers/raster/jp2ecw.rst +++ b/doc/source/drivers/raster/jp2ecw.rst @@ -379,4 +379,3 @@ See Also - Support for non-GDAL specific issues should be directed to the `Hexagon Geospatial public forum `__ -- `GDAL ECW Build Hints `__ diff --git a/doc/source/drivers/raster/jp2lura.rst b/doc/source/drivers/raster/jp2lura.rst deleted file mode 100644 index 817a99fb0dac..000000000000 --- a/doc/source/drivers/raster/jp2lura.rst +++ /dev/null @@ -1,405 +0,0 @@ -.. _raster.jp2lura: - -================================================================================ -JP2Lura -- JPEG2000 driver based on Lurawave library -================================================================================ - -.. shortname:: JP2LURA - -.. versionadded:: 2.2 - -.. build_dependencies:: Lurawave library - -This driver is an implementation of a JPEG2000 reader/writer based on -Lurawave library. - -The driver uses the VSI Virtual File API, so it can read JPEG2000 -compressed NITF files. - -Driver capabilities -------------------- - -.. supports_createcopy:: - -.. supports_georeferencing:: - -.. supports_virtualio:: - -Georeferencing --------------- - -Georeferencing information can come from different sources : internal -(GeoJP2 or GMLJP2 boxes), worldfile .j2w/.wld sidecar files, or PAM -(Persistent Auxiliary metadata) .aux.xml sidecar files. By default, -information is fetched in following order (first listed is the highest -priority): PAM, GeoJP2, GMLJP2, WORLDFILE. - -The allowed sources and their priority order can be changed with the -:config:`GDAL_GEOREF_SOURCES` configuration option (or :oo:`GEOREF_SOURCES` open option) -whose value is a comma-separated list of the following keywords : PAM, -GEOJP2, GMLJP2, INTERNAL (shortcut for GEOJP2,GMLJP2), WORLDFILE, NONE. -Earlier mentioned sources take priority over later ones. A non mentioned source -will be ignored. - -For example setting it to "WORLDFILE,PAM,INTERNAL" will make a -geotransformation matrix from a potential worldfile priority over PAM -or internal JP2 boxes. Setting it to "PAM,WORLDFILE,GEOJP2" will use the -mentioned sources and ignore GMLJP2 boxes. - -Configuration Options ---------------------- - -|about-config-options| -The following configuration options are supported: - -- .. config:: LURA_LICENSE_NUM_1 - :required: YES - - First component of license number. - -- .. config:: LURA_LICENSE_NUM_2 - :required: YES - - Second component of license number. - -Open Options ------------- - -|about-open-options| -The following open option is available: - -- .. oo:: GEOREF_SOURCES - - Define which georeferencing - sources are allowed and their priority order. See - `Georeferencing`_ paragraph. - -Creation Options ----------------- - -|about-creation-options| -The following creation options are available: - -- .. co:: CODEC - :choices: JP2, Codestream - - JP2 will add JP2 boxes around the - codestream data. The value is determined automatically from the file - extension. If it is neither JP2 nor Codestream, JP2 codec is used. - -- .. co:: GMLJP2 - :choices: YES, NO - :default: YES - - Indicates whether a GML box conforming to the OGC - GML in JPEG2000 specification should be included in the file. Unless - :co:`GMLJP2V2_DEF` is used, the version of the GMLJP2 box will be version - 1. - -- .. co:: GMLJP2V2_DEF - :choices: YES, , - - Indicates whether a GML box conforming to - the `OGC GML in JPEG2000, version - 2.0.1 `__ - specification should be included in the file. *filename* must point - to a file with a JSON content that defines how the GMLJP2 v2 box - should be built. See :ref:`GMLJP2v2 definition file - section ` in documentation of - the JP2OpenJPEG driver for the syntax of the JSON configuration file. - It is also possible to - directly pass the JSON content inlined as a string. If filename is - just set to YES, a minimal instance will be built. - -- .. co:: GeoJP2 - :choices: YES, NO - :default: NO - - Indicates whether a UUID/GeoTIFF box conforming to - the GeoJP2 (GeoTIFF in JPEG2000) specification should be included in - the file. Defaults to NO. - -- .. co:: SPLIT_IEEE754 - :choices: YES, NO - :default: NO - - Whether encoding of Float32 bands as 3 - bands with values decomposed according to IEEE-754 structure: first - band (1 bit, signed) with sign bit, second band (8 bits, unsigned) - with exponent value and third band (23 bits, unsigned) with mantissa - value. This is a non-standard extension to encode - floating point values. By default, the sign bit and exponent will be - encoded with the reversible wavelet (even with :co:`REVERSIBLE=NO`), and - the mantissa with the irreversible one. If specifying :co:`REVERSIBLE=YES`, - all 3 components will be encoded with the reversible wavelet. - -- .. co:: NBITS - :choices: - - Bits (precision) for sub-byte files (1-7), - sub-uint16 (9-15), sub-uint32 (17-28). - -- .. co:: QUALITY_STYLE - :choices: PSNR, XXSmall, XSmall, Small, Medium, Large, XLarge, XXLarge - :default: PSNR - - This property tag is used to set the quality mode to be used during - lossy compression. For normal images and situations (1:1 pixel - display, ~50 cm viewing distance) we recommend Small or PSNR. For - quality measurement only PSNR should be used. - -- .. co:: SPEED_MODE - :choices: Fast, Accurate - :default: Fast - - This property tag is used to set the - speed mode to be used during lossy compression. The following modes - are defined. - -- .. co:: RATE - :choices: - :default: 0 - - When specifying this value, the target compressed - file size will be the uncompressed file size divided by RATE. In - general the achieved rate will be exactly the requested size or a few - bytes lower. Will force use of irreversible wavelet. Default value: 0 - (maximum quality). - -- .. co:: QUALITY - :choices: 0, 1-100 - :default: 0 - - Compression to a particular quality is possible - only when using the 9-7 filter with the standard expounded - quantization and no regions of interest. A compression quality may be - specified between 1 (low) and 100 (high). The size of the resulting - JPEG2000 file will depend of the image content. Only used for - irreversible compression. The compression quality cannot be used - together the property RATE. Default value: 0 (maximum quality). When - using this option together with :co:`SPLIT_IEEE754=YES`, the sign bit and - exponent bands will have to be switched to irreversible encoding, - which can lead to huge loss in the reconstructed floating-point - value. - -- .. co:: PRECISION - :choices: - :default: 0 - - For improved efficiency, the library - automatically, depending on the image depth, uses either 16 or 32 bit - representation for wavelet coefficients. The precision property can - be set to force the library to always use 32 bit representations. The - use of 32 bit values may slightly improve image quality and the - expense of speed and memory requirements. Default value: 0 - (automatically select appropriate precision). - -- .. co:: REVERSIBLE - :choices: YES, NO - :default: NO - - YES means use of reversible 5x3 integer-only - filter, NO use of the irreversible DWT 9-7. - -- .. co:: LEVELS - :choices: 0-16 - :default: 5 - - The number of wavelet transformation - levels can be set using this property. Valid values are in the range - 0 (no wavelet analysis) to 16 (very fine analysis). The memory - requirements and compression time increases with the number of - transformation levels. A reasonable number of transformation levels - is in the 4-6 range. - -- .. co:: QUANTIZATION_STYLE - :choices: DERIVED, EXPOUNDED - :default: EXPOUNDED - - This property may only be - set when the irreversible filter (9_7) is used. The quantization - steps can either be derived from a bases quantization step, DERIVED, - or calculated for each image sub-band, EXPOUNDED. The EXPOUNDED style - is recommended when using the irreversible filter. - -- .. co:: TILEXSIZE - :choices: - :default: 0 - - Tile width. An image can be split into - smaller tiles, with each tile independently compressed. The basic - tile size and the offset to the first tile on the virtual compression - reference grid can be set using these properties. The first tile must - contain the first image pixel. The tiling of an image is recommended - only for very large images. Default values: (0) One Tile containing - the complete image. If the image dimension exceeds 15000x15000, it - will be tiled with tiles of dimension 1024x1024. - -- .. co:: TILEYSIZE - :choices: - :default: 0 - - Tile height. An image can be split into - smaller tiles, with each tile independently compressed. The basic - tile size and the offset to the first tile on the virtual compression - reference grid can be set using these properties. The first tile must - contain the first image pixel. The tiling of an image is recommended - only for very large images. Default values: (0) One Tile containing - the complete image. If the image dimension exceeds 15000x15000, it - will be tiled with tiles of dimension 1024x1024. - -- .. co:: TLM - :choices: YES, NO - :default: NO - - (TiLe Marker) The efficiency of decoding regions in a - tiled image may be improved by " the usage of a tile length marker. - Tile length markers contain the " position of each tile in a JPEG2000 - codestream, enabling faster access " to tiled data. - -- .. co:: PROGRESSION - :choices: LRCP, RLCP, RPCL, PCRL, CPRL - :default: LRCP - - The organization of the - coded data in the file can be set by this property tag. The following - progression orders are defined: LRCP = Quality progressive, LCP = - Resolution then quality progressive, RPCL = Resolution then position - progressive, PCRL = Position progressive, CPRL = Color/channel - progressive. The setting LRCP (quality) is most useful when used with - several layers. The PCRL (position) should be used with precincts. - -- .. co:: JPX - :choices: YES, NO - :default: YES - - Whether to advertise JPX features, and add a Reader - requirement box, when a GMLJP2 box is written (for GMLJP2 v2, the - branding will also be "jpx "). This option should - not be used unless compatibility problems with a reader occur. - -- .. co:: CODEBLOCK_WIDTH - :choices: - :default: 64 - - Codeblock width: power of two value - between 4 and 1024. Note that CODEBLOCK_WIDTH \* - CODEBLOCK_HEIGHT must not be greater than 4096. For PROFILE_1 - compatibility, CODEBLOCK_WIDTH must not be greater than 64. - -- .. co:: CODEBLOCK_HEIGHT - :choices: - :default: 64 - - Codeblock height: power of two value - between 4 and 1024. Note that CODEBLOCK_WIDTH \* - CODEBLOCK_HEIGHT must not be greater than 4096. For PROFILE_1 - compatibility, CODEBLOCK_HEIGHT must not be greater than 64. - -- .. co:: ERROR_RESILIENCE - :choices: YES, NO - :default: NO - - This option improves error resilient in - JPEG2000 streams or for special codecs (e.g. hardware coder) for a - faster compression/ decompression. This option will increase the file - size slightly when generating a code stream with the same image - quality. - -- .. co:: WRITE_METADATA - :choices: YES, NO - - Whether metadata should be written, in a - dedicated JP2 'xml ' box. Defaults to NO. The content of the 'xml ' - - :: - - - - bar - - - bar - - - - - - - - If there are metadata domain whose name starts with "xml:BOX\_", they - will be written each as separate JP2 'xml ' box. - - If there is a metadata domain whose name is "xml:XMP", its content - will be written as a JP2 'uuid' XMP box. - -- .. co:: MAIN_MD_DOMAIN_ONLY - :choices: YES, NO - :default: NO - - (Only if :co:`WRITE_METADATA=YES`) Whether - only metadata from the main domain should be written. - -- .. co:: USE_SRC_CODESTREAM - :choices: YES, NO - - (EXPERIMENTAL!) When source dataset is - JPEG2000, whether to reuse the codestream of the source dataset - unmodified. Defaults to NO. Note that enabling that feature might - result in inconsistent content of the JP2 boxes w.r.t. to the content - of the source codestream. Most other creation options will be ignored - in that mode. Can be useful in some use cases when adding/correcting - georeferencing, metadata, ... - -Lossless compression -~~~~~~~~~~~~~~~~~~~~ - -Lossless compression can be achieved if REVERSIBLE=YES is used (and RATE -is not specified). - -Vector information ------------------- - -A JPEG2000 file containing a GMLJP2 v2 box with GML feature collections -and/or KML annotations embedded can be opened as a vector file with the -OGR API. For example: - -:: - - ogrinfo -ro my.jp2 - - INFO: Open of my.jp2' - using driver `JP2Lura' successful. - 1: FC_GridCoverage_1_rivers (LineString) - 2: FC_GridCoverage_1_borders (LineString) - 3: Annotation_1_poly - -Feature collections can be linked from the GMLJP2 v2 box to a remote -location. By default, the link is not followed. It will be followed if -the open option OPEN_REMOTE_GML is set to YES. - -Bugs ----- - -Proper support of JPEG-2000 images with -Int32/UInt32/Float32-IEEE754-split on Linux 64 bits require a v2.1.00.17 -or later SDK. - -See Also --------- - -- `LuraTech JPEG-2000 - SDK `__ - -Other JPEG2000 GDAL drivers : - -- :ref:`JP2OpenJPEG: based on Openjpeg library (open - source) ` - -- :ref:`JP2ECW: based on Erdas ECW library - (proprietary) ` - -- :ref:`JP2MRSID: based on LizardTech MrSID library - (proprietary) ` - -- :ref:`JP2KAK: based on Kakadu library (proprietary) ` diff --git a/doc/source/drivers/raster/jpegxl.rst b/doc/source/drivers/raster/jpegxl.rst index 4ed85841b58f..4ad829843a4d 100644 --- a/doc/source/drivers/raster/jpegxl.rst +++ b/doc/source/drivers/raster/jpegxl.rst @@ -97,6 +97,8 @@ The following creation options are available: If set to NO, or in AUTO mode if the source dataset does not use JPEG compression, the regular conversion code path is taken, resulting in a lossless or lossy copy depending on the LOSSLESS setting. + AUTO mode defaults to NO, if EFFORT, DISTANCE, ALPHA_DISTANCE or QUALITY + options are used. - .. co:: EFFORT :choices: 1-9 @@ -106,7 +108,7 @@ The following creation options are available: The higher, the smaller file and slower compression time. - .. co:: DISTANCE - :choices: 0.1-15 + :choices: 0.01-25 :default: 1.0 Distance level for lossy JPEG-XL compression. @@ -118,7 +120,7 @@ The following creation options are available: The recommended range is [0.5,3]. - .. co:: ALPHA_DISTANCE - :choices: -1, 0, 0.1-15 + :choices: -1, 0, 0.01-25 :default: -1.0 :since: 3.7 diff --git a/doc/source/drivers/raster/mbtiles.rst b/doc/source/drivers/raster/mbtiles.rst index 052acc1ff4d9..5c52281ec31a 100644 --- a/doc/source/drivers/raster/mbtiles.rst +++ b/doc/source/drivers/raster/mbtiles.rst @@ -217,7 +217,7 @@ Tile formats MBTiles can store tiles in PNG, JPEG or WEBP (since 3.8). Support for those tile formats depend if the underlying drivers are available -in GDAL. By default, GDAL will PNG tiles. +in GDAL. By default, GDAL will produce PNG tiles. It is possible to select the tile format by setting the creation/open option TILE_FORMAT to one of PNG, PNG8, JPEG or WEBP. When using JPEG, diff --git a/doc/source/drivers/raster/mem.rst b/doc/source/drivers/raster/mem.rst index 223ead3d0f79..ae18bd9b3220 100644 --- a/doc/source/drivers/raster/mem.rst +++ b/doc/source/drivers/raster/mem.rst @@ -63,14 +63,29 @@ or the next. - GEOTRANSFORM: Set the affine transformation coefficients. 6 real numbers with '/' as separator (optional) -- SPATIALREFERENCE: (GDAL >= 3.7) Set the projection. The coordinate reference - systems that can be passed are anything supported by the - OGRSpatialReference.SetFromUserInput() as per '-a_srs' in +- SPATIALREFERENCE: (GDAL >= 3.7) Set the projection. The coordinate reference + systems that can be passed are anything supported by the + OGRSpatialReference.SetFromUserInput() as per '-a_srs' in :ref:`gdal_translate`. If the passed string includes comma or double-quote characters (typically WKT), it should be surrounded by double-quote characters and the double-quote characters inside it should be escaped with anti-slash. e.g ``SPATIALREFERENCE="GEOGCRS[\"WGS 84\",[... snip ...],ID[\"EPSG\",4326]]"`` +.. warning:: + + Starting with GDAL 3.10, opening a MEM dataset using the above syntax is no + longer enabled by default for security reasons. + If you want to allow it, define the ``GDAL_MEM_ENABLE_OPEN`` configuration + option to ``YES``, or build GDAL with the ``GDAL_MEM_ENABLE_OPEN`` compilation + definition. + + .. config:: GDAL_MEM_ENABLE_OPEN + :choices: YES, NO + :default: NO + :since: 3.10 + + Whether opening a MEM dataset with the ``MEM:::`` syntax is allowed. + Creation Options ---------------- diff --git a/doc/source/drivers/raster/msg.rst b/doc/source/drivers/raster/msg.rst index 2ad9c9d03740..357c14a4c4e1 100644 --- a/doc/source/drivers/raster/msg.rst +++ b/doc/source/drivers/raster/msg.rst @@ -35,37 +35,8 @@ Driver capabilities Build Instructions ------------------ -CMake builds -++++++++++++ - See the ``GDAL_USE_PUBLICDECOMPWT`` option of :ref:`building_from_source`. -Other build systems -+++++++++++++++++++ - -Clone the EUMETSAT library for wavelet decompression into ``frmts/msg``. - -If you are building with Visual Studio 6.0, extract the .vc makefiles -for the PublicDecompWT from the file `PublicDecompWTMakefiles.zip` -stored in that directory. - -If you build using the GNUMakefile, use *--with-msg* option to enable -MSG driver: - -:: - - ./configure --with-msg - -If you find that some adjustments are needed in the makefile and/or the msg -source files, please "commit" them. The EUMETSAT library promises to be -"platform independent", but as we are working with Microsoft Windows and -Visual Studio 6.0, we did not have the facilities to check if the rest -of the msg driver is. Furthermore, apply steps 4 to 7 from the :ref:`raster_driver_tut`, section "Adding -Driver to GDAL Tree". - -MSG Wiki page is available at http://trac.osgeo.org/gdal/wiki/MSG. It's -dedicated to document building and usage hints - Specification of Source Dataset ------------------------------- diff --git a/doc/source/drivers/raster/netcdf.rst b/doc/source/drivers/raster/netcdf.rst index 78e95193eb70..f87430d54a75 100644 --- a/doc/source/drivers/raster/netcdf.rst +++ b/doc/source/drivers/raster/netcdf.rst @@ -287,7 +287,7 @@ The following open options are available: valid_min, valid_max or valid_range attributes. - .. oo:: IGNORE_XY_AXIS_NAME_CHECKS - :choices: YES, NOA + :choices: YES, NO :default: NO :since: 3.4.2 @@ -617,6 +617,17 @@ Configuration Options geotransform has been found, and that geotransform is within the bounds -180,360 -90,90, if YES assume OGC:CRS84. +- .. config:: GDAL_NETCDF_REPORT_EXTRA_DIM_VALUES + :choices: YES, NO + :default: NO + :since: 3.10.1 + + For a netCDF dataset stored on a remote file system (``/vsicurl/``, ``/vsis3/``), + getting the content of the ``NETCDF_DIM_{dim_name}_VALUES`` metadata item + can be a slow operation when the dimension is unlimited. It is thus disabled + by default for such remote files. By setting this configuration option to YES, + you force GDAL to get the content of such metadata items. + VSI Virtual File System API support ----------------------------------- @@ -750,9 +761,6 @@ This driver is compiled with the UNIDATA NetCDF library. You need to download or compile the NetCDF library before configuring GDAL with NetCDF support. -See `NetCDF GDAL wiki `__ for -build instructions and information regarding HDF4, NetCDF-4 and HDF5. - See Also: --------- diff --git a/doc/source/drivers/raster/nitf.rst b/doc/source/drivers/raster/nitf.rst index 6db8c38ede1e..4d95ded1e8ba 100644 --- a/doc/source/drivers/raster/nitf.rst +++ b/doc/source/drivers/raster/nitf.rst @@ -131,10 +131,12 @@ The following creation options are available: CreateCopy() and/or Create() methods. See below paragraph for specificities. - .. co:: QUALITY - :choices: 10-100 :default: 75 - JPEG quality 10-100 + For JPEG, quality as integer values in the 10-100 range + For JPEG2000, quality as a floating-point value in >0 - 100 range. + When JPEG2000_DRIVER=JP2OpenJPEG and PROFILE is not one of the NPJE ones, + several quality layers can be specified as a comma-separated list of values. - .. co:: PROGRESSIVE :choices: YES, NO diff --git a/doc/source/drivers/raster/nitf_advanced.rst b/doc/source/drivers/raster/nitf_advanced.rst index 1420b704f865..95fbde783884 100644 --- a/doc/source/drivers/raster/nitf_advanced.rst +++ b/doc/source/drivers/raster/nitf_advanced.rst @@ -338,3 +338,11 @@ Example: gdal_translate first_image.tif dest.tif -co NUMI=3 -co NUMDES=1 gdal_translate second_image.tif dest.tif -co APPEND_SUBDATASET=YES -co IC=C3 -co IDLVL=2 gdal_translate third_image.tif dest.tif -co APPEND_SUBDATASET=YES -co IC=C8 -co IDLVL=3 -co "DES=DES1={des_content}" + +Reading SAR products +-------------------- + +Starting with GDAL 3.11, NITF products whose ``ICAT`` field is set to ``SAR`` +and which have bands with ``I`` (in-phase) and ``Q`` (quadrature) ``ISUBCAT`` +values will be represented as a single-band of complex type where in-phase is +the real part and quadrature the imaginary part. diff --git a/doc/source/drivers/raster/pdf.rst b/doc/source/drivers/raster/pdf.rst index 95c077f86406..92a53c35bfd3 100644 --- a/doc/source/drivers/raster/pdf.rst +++ b/doc/source/drivers/raster/pdf.rst @@ -193,7 +193,7 @@ at the first access to a raster block, the whole page will be rasterized (with Poppler), which can be a slow operation. Note: some raster-only PDF files (such as some -USGS GeoPDF files), that are regularly tiled are exposed as tiled +USGS PDF files), that are regularly tiled are exposed as tiled dataset by the GDAL PDF driver, and can be rendered with any backends. Only a few of the possible Datums available in the OGC best practice @@ -809,7 +809,7 @@ See also Specifications : -- `OGC GeoPDF Encoding Best Practice Version 2.2 +- `OGC PDF Georegistration Encoding Best Practice Version 2.2 (08-139r3) `__ - `Adobe Supplement to ISO 32000 `__ diff --git a/doc/source/drivers/raster/pds4.rst b/doc/source/drivers/raster/pds4.rst index d584853f04a8..0dd5add475e9 100644 --- a/doc/source/drivers/raster/pds4.rst +++ b/doc/source/drivers/raster/pds4.rst @@ -194,10 +194,7 @@ The following dataset creation options are available: and not creating from an existing PDS4 file, the data/pds4_template.xml file will be used. For GDAL utilities to find this default PDS4 template, GDAL's data directory should be - defined in your environment (typically on Windows builds). Consult - the - `wiki `__ - for more information. + defined in your environment (typically on Windows builds). - .. co:: LATITUDE_TYPE :choices: Planetocentric, Planetographic @@ -537,12 +534,6 @@ Converting a shapefile to a PDS4 dataset with a CSV-delimited table $ ogr2ogr my_out_pds4.xml in.shp -Limitations ------------ - -As a new driver and new format, please report any issues to the bug -tracker, as explained on the `wiki `__ - See Also: --------- diff --git a/doc/source/drivers/raster/postgisraster.rst b/doc/source/drivers/raster/postgisraster.rst index 3927e23e5738..55266b389f32 100644 --- a/doc/source/drivers/raster/postgisraster.rst +++ b/doc/source/drivers/raster/postgisraster.rst @@ -130,6 +130,6 @@ See Also -------- - `GDAL PostGISRaster driver - Wiki `__ + Wiki `__ - `PostGIS Raster documentation `__ diff --git a/doc/source/drivers/raster/rcm.rst b/doc/source/drivers/raster/rcm.rst new file mode 100644 index 000000000000..cbe6f2d89531 --- /dev/null +++ b/doc/source/drivers/raster/rcm.rst @@ -0,0 +1,56 @@ +.. _raster.rcm: + +================================================================================ +RCM -- RADARSAT Constellation Mission Product +================================================================================ + +.. versionadded:: 3.11 + +.. shortname:: RCM + +.. built_in_by_default:: + +This driver will read RADARSAT Constellation Mission polarimetric products. + +The RADARSAT Constellation Mission XML products are distributed with a primary +XML file called product.xml, and a set of supporting XML data files with the +actual imagery stored in TIFF files. +The RCM driver will be used if the product.xml or the containing directory is +selected, and it can treat all the imagery as one consistent dataset. + +The RCM driver also reads geolocation tiepoints from the product.xml file and +represents them as GCPs on the dataset. + +Driver capabilities +------------------- + +.. supports_georeferencing:: + +.. supports_virtualio:: + +Data Calibration +---------------- + +If you wish to have GDAL apply a particular calibration LUT to the data +when you open it, you have to open the appropriate subdatasets. +The following subdatasets exist within the SUBDATASET domain for RCM products: + +- uncalibrated: open with ``RCM_CALIB:UNCALIB:`` prepended to filename +- beta\ :sub:`0`: open with ``RCM_CALIB:BETA0:`` prepended to filename +- sigma\ :sub:`0`: open with ``RCM_CALIB:SIGMA0:`` prepended to filename +- Gamma: open with ``RCM_CALIB:GAMMA:`` prepended to filename + +Note that geocoded (GCC/GCD) products do not have this functionality available. +Also be aware that the LUTs must be in the product directory where specified in +the product.xml, otherwise loading the product with the calibration LUT applied +will fail. + +One caveat worth noting is that the RCM driver will supply the calibrated data +as GDT_Float32 or GDT_CFloat32 depending on the type of calibration selected. +The uncalibrated data is provided as GDT_Int16/GDT_Byte/GDT_CInt16, also +depending on the type of product selected. + +See Also +-------- + +- RADARSAT Constellation Mission Product Specification RCM-SP-52-9092 diff --git a/doc/source/drivers/raster/s102.rst b/doc/source/drivers/raster/s102.rst index 85ccbd6e397c..3245d29f31ed 100644 --- a/doc/source/drivers/raster/s102.rst +++ b/doc/source/drivers/raster/s102.rst @@ -11,7 +11,7 @@ S102 -- S-102 Bathymetric Surface Product .. versionadded:: 3.8 This driver provides read-only support for bathymetry data in the S-102 format, -which is a specific product profile in an HDF5 file +which is a specific product profile in an HDF5 file. S-102 files have two image bands representing depth (band 1), uncertainty (band 2) values for each cell in a raster grid area. @@ -25,6 +25,11 @@ Georeferencing is reported. Nodata, minimum and maximum values for each band are also reported. +Supported versions of the specification are S-102 v2.1, v2.2 and v3.0 +(support for v3.0 spatial metadata added in GDAL 3.10. Multiple grids per +file, as permitted by S-102 v3.0, are not supported currently. Only the +first one will be reported.) + Driver capabilities ------------------- @@ -63,12 +68,16 @@ The following open options are supported: Spatial metadata support ------------------------ -Starting with GDAL 3.9, GDAL can handle QualityOfSurvey spatial metadata. +Starting with GDAL 3.9, GDAL can handle QualityOfSurvey +(or QualityOfBathymetryCoverage in S102 v3.0) spatial metadata. When such spatial metadata is present, the subdataset list will include -a name of the form ``S102:"{filename}":QualityOfSurvey`` +a name of the form ``S102:"{filename}":QualityOfSurvey`` ( +or ``S102:"{filename}":QualityOfBathymetryCoverage`` in S102 v3.0) -The ``/QualityOfSurvey/featureAttributeTable`` dataset is exposed as a +The ``/QualityOfSurvey/featureAttributeTable`` +(``/QualityOfBathymetryCoverage/featureAttributeTable`` in S102 v3.0) +dataset is exposed as a GDAL Raster Attribute Table associated to the GDAL raster band. The pixel values of the raster match the ``id`` column of the Raster Attribute Table. diff --git a/doc/source/drivers/raster/snap_tiff.rst b/doc/source/drivers/raster/snap_tiff.rst new file mode 100644 index 000000000000..31ea7604c67c --- /dev/null +++ b/doc/source/drivers/raster/snap_tiff.rst @@ -0,0 +1,39 @@ +.. _raster.snap_tiff: + +================================================================================ +SNAP_TIFF -- Sentinel Application Processing GeoTIFF +================================================================================ + +.. versionadded:: 3.10 + +.. shortname:: SNAP_TIFF + +.. built_in_by_default:: + +This driver deals specifically with GeoTIFF files produced by the +Sentinel Application Processing (SNAP) toolbox. + +Such files are formulated in a way that makes it difficult to read them with the +generic :ref:`raster.gtiff` driver. + +Driver capabilities +------------------- + +.. supports_georeferencing:: + +.. supports_virtualio:: + +Georeferencing +-------------- + +SNAP GeoTIFF files contain a geolocation array (stored as a regular grid of +GeoTIFF tie points). It is reported in the ``GEOLOCATION`` metadata domain. + +The 4 corners of the geolocation array are also reported as ground control points +for faster (but less accurate) georeferencing. + +Metadata +-------- + +Extensive metadata following DIMAP conventions is reported in the ``xml:DIMAP`` +metadata domain. diff --git a/doc/source/drivers/raster/vrt.rst b/doc/source/drivers/raster/vrt.rst index a7399412e6c9..a5d16963ec40 100644 --- a/doc/source/drivers/raster/vrt.rst +++ b/doc/source/drivers/raster/vrt.rst @@ -58,6 +58,8 @@ This tutorial will cover the .vrt file format (suitable for users editing .vrt files), and how .vrt files may be created and manipulated programmatically for developers. +.. _raster_vrt_creation_options: + Creation options ---------------- @@ -403,6 +405,31 @@ cubicspline,lanczos,average,mode.
    + +Starting with GDAL 3.11, it is also possible to use a in-line VRTDataset as +the source by using the VRTDataset element instead of SourceFilename. + +.. code-block:: xml + + + + + + ../byte.tif + 1 + + + + + + + 1 + + + + + + ComplexSource ~~~~~~~~~~~~~ @@ -1535,6 +1562,8 @@ contrary to the Python interactive interpreter, the current path is not automatically added when used from GDAL. So you may need to define the **PYTHONPATH** environment variable if you get ModuleNotFoundError exceptions. +.. _raster_vrt_security_implications: + Security implications ********************* @@ -1601,7 +1630,7 @@ Given the following :file:`mandelbrot.py` file : #print('Using numba') g_max_iterations = 100 except Exception: - class jit(object): + class jit: def __init__(self, nopython = True, nogil = True): pass diff --git a/doc/source/drivers/raster/zarr.rst b/doc/source/drivers/raster/zarr.rst index 58faf76229b5..9f636a6813cb 100644 --- a/doc/source/drivers/raster/zarr.rst +++ b/doc/source/drivers/raster/zarr.rst @@ -504,7 +504,10 @@ The following options are creation options of the classic raster API only: When writing a multi-band dataset as a 3D Zarr array, whether the band dimension should be the first one/slowest varying one (BAND), or the - last one/fastest varying one (INTERLEAVE) + last one/fastest varying one (PIXEL) + The default value is BAND in Create() mode. In CreateCopy() mode, the + default value is the value of the INTERLEAVE metadata item of the + IMAGE_STRUCTURE metadata domain of the source dataset, if set. Examples diff --git a/doc/source/drivers/vector/adbc.rst b/doc/source/drivers/vector/adbc.rst new file mode 100644 index 000000000000..40a312323367 --- /dev/null +++ b/doc/source/drivers/vector/adbc.rst @@ -0,0 +1,137 @@ +.. _vector.adbc: + +ADBC -- Arrow Database Connectivity +=================================== + +.. versionadded:: 3.11 + +.. shortname:: ADBC + +ADBC is a set of APIs and libraries for Arrow-native access to database. + +This driver has 2 modes: + +- either it has been built against the ``adbc-driver-manager`` library. In that + case, it can directly be used to connect to available ADBC drivers, and expose + content as classic OGR features, or as a ArrowArrayStream. + In that mode the driver metadata exposes the ``HAS_ADBC_DRIVER_MANAGER`` + metadata item. +- or it has not, in which case applications embedding GDAL must use + :cpp:func:`GDALSetAdbcLoadDriverOverride` as detailed in a below paragraph. + Note that use of that function can also be done even if the driver has been built + against the ``adbc-driver-manager`` library. + +Consult the `installation instruction `__ +for the various ADBC drivers. At time of writing, there are drivers for +SQLite3, PostgreSQL, Snowflake, BigQuery, DuckDB, Flight SQL, etc. + +The driver is read-only, and there is no support for spatial data currently. + +Connection string +----------------- + +Several connection strings are supported: + +- ``ADBC:{some_uri}``, together with the ``ADBC_DRIVER`` open option. +- a SQLite3 database filename, if the ``adbc_driver_sqlite`` is available. +- a DuckDB database filename, if the :file:`libduckdb.so`, :file:`libduckdb.dylib` + or :file:`duckdb.dll` is available (and it is in a system location, or can be + located through LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on MacOSX or PATH on Windows). +- a Parquet database filename, if the :file:`libduckdb.so`, :file:`libduckdb.dylib` + or :file:`duckdb.dll` is available (and it is in a system location, or can be + located through LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on MacOSX or PATH on Windows). +- a PostgreSQL URI starting with ``postgresql://``, if the ``adbc_driver_postgresql`` is available. + +Note: if present, the :ref:`vector.sqlite`, :ref:`vector.gpkg` or +:ref:`vector.parquet` drivers are registered before the ADBC driver, so they will +be used in priority when available. The ``ADBC:`` prefix or the ``-if ADBC`` +switch of :program:`ogrinfo` or :program:`ogr2ogr` can be used to use the ADBC +driver instead. + +Dataset open options +-------------------- + +|about-open-options| +The following open options are supported: + +- .. oo:: ADBC_DRIVER + :choices: + + ADBC driver name. Examples: ``adbc_driver_sqlite``, ``adbc_driver_postgresql``, + ``adbc_driver_bigquery``, ``adbc_driver_snowflake`` or a path to the + DuckDB shared library. + +- .. oo:: SQL + :choices: + + A SQL-like statement recognized by the driver, used to create a result + layer from the dataset. + +- .. oo:: ADBC_OPTION_xxx + :choices: + + Custom ADBC option to pass to AdbcDatabaseSetOption(). Options are + driver specific. + For example ``ADBC_OPTION_uri=some_value`` to pass the ``uri`` option. + +- .. oo:: PRELUDE_STATEMENTS + :choices: + + SQL-like statement recognized by the driver that must be executed before + discovering layers. Can be repeated multiple times. + For example ``PRELUDE_STATEMENTS=INSTALL spatial`` and + ``PRELUDE_STATEMENTS=LOAD spatial`` to load DuckDB spatial extension. + +"table_list" special layer +-------------------------- + +For PostgreSQL, SQLite3, DuckDB and Parquet datasets, the driver automatically +instantiates OGR layers from available tables. +For other databases, the user must explicit provide a SQL open option or issue +a :cpp:func:`GDALDataset::ExecuteSQL` request. +To facilitate that process, a special OGR ``table_list`` layer can be queried +through :cpp:func:`GDALDataset::GetLayerByName` (or as the layer name with +:program:`ogrinfo`). +It returns for each table a OGR feature with the following fields (some +potentially unset or with an empty string): ``catalog_name``, ``schema_name``, +``table_name``, ``table_type``. + +Custom driver entry point +------------------------- + +A custom driver entry point can be specified by applications by calling +:cpp:func:`GDALSetAdbcLoadDriverOverride` (defined in header :file:`gdal_adbc.h`) +before using the driver. The specified init function will be used by the +GDAL ADBC driver as a way of locating and loading the ADBC driver if GDAL was +not built with ADBC Driver Manager support or if an embedding application has +an updated or augmented collection of drivers available. + +Examples +-------- + +- Assuming :file:`libduckdb.so`, :file:`libduckdb.dylib` or :file:`duckdb.dll` + is available (and it is in a system location, or can be located through + LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on MacOSX or PATH on Windows). + + Convert a Parquet file to GeoPackage: + + :: + + ogr2ogr out.gpkg in.parquet + + +- Assuming :file:`libduckdb.so`, :file:`libduckdb.dylib` or :file:`duckdb.dll` + is available (and it is in a system location, or can be located through + LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on MacOSX or PATH on Windows). + + Convert a DuckDB database to GeoPackage: + + :: + + ogr2ogr out.gpkg in.duckdb + + +See Also +-------- + +`ADBC: Arrow Database Connectivity `__ diff --git a/doc/source/drivers/vector/aivector.rst b/doc/source/drivers/vector/aivector.rst new file mode 100644 index 000000000000..41c230f45dd2 --- /dev/null +++ b/doc/source/drivers/vector/aivector.rst @@ -0,0 +1,32 @@ +.. _vector.aivector: + +Artificial intelligence powered vector driver +============================================= + +.. versionadded:: 3.11 + +.. shortname:: AIVector + +.. built_in_by_default:: + +This driver builds on many years of self-funded investments from the GDAL team on AI +technologies to bring you the ultimate driver that can read any vector format. +After that one, no need for any new vector driver! + +The open syntax is ``AIVector:{filename}``, or directly specify the filename and +force the use of the AIVector driver with the ``-if`` flag of ogrinfo or ogr2ogr. +No options at all. Just enjoy the true power of AI. + +.. note:: We are open to external investors to develop the write side of the driver. + +Examples +-------- + +:: + + ogrinfo -if AIVector undocumented_proprietary_format.bin -al + +.. note:: + + The above works even if you make a typo in the filename. The driver will + automatically figure out the filename you meant. diff --git a/doc/source/drivers/vector/arrow.rst b/doc/source/drivers/vector/arrow.rst index 27cfb3bf80e0..1d4bc48a73a1 100644 --- a/doc/source/drivers/vector/arrow.rst +++ b/doc/source/drivers/vector/arrow.rst @@ -157,9 +157,9 @@ particular outside of the context of the OGR Arrow driver, by: GetGDALDriverManager()->GetDriverByName("ARROW")->GetMetadata(), the Arrow VSI file system will be also registered. -- Prefixing any GDAL file name with the ``vsi://`` URI scheme prefix. In addition +- Prefixing any GDAL file name with the ``gdalvsi://`` URI scheme prefix. In addition to any potential vsi prefix in the GDAL file name. So the ``/vsicurl/http://example.com`` - GDAL file name becomes the ``vsi:///vsicurl/http://example.com`` Arrow URI. + GDAL file name becomes the ``gdalvsi:///vsicurl/http://example.com`` Arrow URI. Links ----- diff --git a/doc/source/drivers/vector/eeda.rst b/doc/source/drivers/vector/eeda.rst index 90717adce691..8e754b2ea84b 100644 --- a/doc/source/drivers/vector/eeda.rst +++ b/doc/source/drivers/vector/eeda.rst @@ -40,6 +40,12 @@ The following open options are available: To specify the collection if not specified in the connection string. +- .. oo:: VSI_PATH_FOR_AUTH + :since: 3.10 + + /vsigs/... path onto which a GOOGLE_APPLICATION_CREDENTIALS path specific + option is set + Authentication methods ---------------------- @@ -48,7 +54,9 @@ The following authentication methods can be used: - Authentication Bearer header passed through the EEDA_BEARER or :config:`EEDA_BEARER_FILE` configuration options. - Service account private key file, through the - :config:`GOOGLE_APPLICATION_CREDENTIALS` configuration option. + :config:`GOOGLE_APPLICATION_CREDENTIALS` configuration option, or set + as a path-specific option whose value is set in the VSI_PATH_FOR_AUTH + open option. - OAuth2 Service Account authentication through the :config:`EEDA_PRIVATE_KEY`/ :config:`EEDA_PRIVATE_KEY_FILE` + diff --git a/doc/source/drivers/vector/gml.rst b/doc/source/drivers/vector/gml.rst index 6b05f1213f95..8486318ac09a 100644 --- a/doc/source/drivers/vector/gml.rst +++ b/doc/source/drivers/vector/gml.rst @@ -115,6 +115,12 @@ The following configuration options are available: Equivalent of :oo:`READ_MODE`. See :ref:`gml_performance`. +- .. config:: GML_DOWNLOAD_SCHEMA + :choices: YES, NO + :since: 3.10 + + Equivalent of :oo:`DOWNLOAD_SCHEMA`. + - .. config:: GML_USE_SCHEMA_IMPORT :choices: YES, NO @@ -614,8 +620,8 @@ The following open options are supported: :choices: YES, NO :default: YES - Whether to download the - remote application schema if needed (only for WFS currently). + Whether to download the remote application schema if needed + (only if the document looks like a WFS response currently). - .. oo:: REGISTRY :choices: diff --git a/doc/source/drivers/vector/gpkg.rst b/doc/source/drivers/vector/gpkg.rst index 77c8c5364dc7..634ee61fd310 100644 --- a/doc/source/drivers/vector/gpkg.rst +++ b/doc/source/drivers/vector/gpkg.rst @@ -809,6 +809,18 @@ Examples -sql "SELECT poly.id, other.foo FROM poly JOIN other_schema.other USING (id)" \ -oo PRELUDE_STATEMENTS="ATTACH DATABASE 'other.gpkg' AS other_schema" +Secure deletion +--------------- + +Depending on how SQLite3 is built, `secure deletion `__ +might or might not be enabled. +Starting with GDAL 3.10, secure deletion is always enabled, unless +``SECURE_DELETE`` is specified through the :config:`OGR_SQLITE_PRAGMA` +configuration option. +Note that secure deletion does not recover potential lost space, so running +a `VACUUM `__ query is recommended to fully +optimized a database that has been subject to updates or deletions. + See Also -------- diff --git a/doc/source/drivers/vector/index.rst b/doc/source/drivers/vector/index.rst index 0ac42608c26a..411189072692 100644 --- a/doc/source/drivers/vector/index.rst +++ b/doc/source/drivers/vector/index.rst @@ -22,6 +22,8 @@ Vector drivers :maxdepth: 1 :hidden: + adbc + aivector amigocloud arrow avcbin diff --git a/doc/source/drivers/vector/libkml.rst b/doc/source/drivers/vector/libkml.rst index ee7ac9114270..b1d9eb9e8d9c 100644 --- a/doc/source/drivers/vector/libkml.rst +++ b/doc/source/drivers/vector/libkml.rst @@ -587,6 +587,13 @@ For example, if you want a field called 'Cities' to map to the tag in KML, you can set a configuration option. Note these are independent of layer creation and dataset creation options' ``. +- .. config:: LIBKML_ID_FIELD + :default: id + :since: 3.10 + + Name of the string field that maps to the kml attribute + ` `__. + - .. config:: LIBKML_NAME_FIELD :default: name diff --git a/doc/source/drivers/vector/oapif.rst b/doc/source/drivers/vector/oapif.rst index 52430bbf9fe4..0f044be6d43a 100644 --- a/doc/source/drivers/vector/oapif.rst +++ b/doc/source/drivers/vector/oapif.rst @@ -58,6 +58,9 @@ evaluated on client-side. Rectangular spatial filtering is forward to the server as well. +Starting with GDAL 3.10, the ``DATETIME`` open option can also be specified for +temporal filtering. + CRS support ----------- @@ -141,6 +144,13 @@ The following open options are available: "GIS friendly" order, with longitude/easting first, latitude/northing second. Do not set this option unless actual problems arise. +- .. oo:: DATETIME + :since: 3.10 + + Temporal filter. Its value should match the ones mentioned at + `paragraph Parameter datetime of the OGC API Features specification `__ + + Examples -------- diff --git a/doc/source/drivers/vector/osm.rst b/doc/source/drivers/vector/osm.rst index ba74354f9819..eddd479d8e9e 100644 --- a/doc/source/drivers/vector/osm.rst +++ b/doc/source/drivers/vector/osm.rst @@ -10,6 +10,17 @@ OSM - OpenStreetMap XML and PBF This driver reads OpenStreetMap files, in .osm (XML based) and .pbf (optimized binary) formats. +The driver reconstructs point, line and polygon geometries from the OpenStreetMap +base objects, which are nodes, ways and relations. Such operation can be very +slow for large files. Consequently, except for small extracts of the +OSM database (that is .pbf files of a few megabytes at most), using this driver +for interactive reading is not appropriate. It is better used to import an OSM file +into a proper GIS format such as GeoPackage. +Even if the driver can theoretically deal with arbitrarily large OSM files, +it is not recommended to use it to import the whole planet. +A tool such as `osm2pgsql `__ which imports into a PostgreSQL +database is much better suited for such operation. + The driver is available if GDAL is built with SQLite support and, for .osm XML files, with Expat support. @@ -204,7 +215,7 @@ You can convert a .osm or .pbf file without downloading it : :: - wget -O - http://www.example.com/some.pbf | + wget -O - http://www.example.com/some.pbf | ogr2ogr -f SQLite my.sqlite /vsistdin/ or @@ -216,7 +227,7 @@ And to combine the above steps : :: - wget -O - http://www.example.com/some.osm.bz2 | + wget -O - http://www.example.com/some.osm.bz2 | bzcat | ogr2ogr -f SQLite my.sqlite /vsistdin/ Open options diff --git a/doc/source/drivers/vector/pg.rst b/doc/source/drivers/vector/pg.rst index f1f4bac2d085..b6857c97b4a1 100644 --- a/doc/source/drivers/vector/pg.rst +++ b/doc/source/drivers/vector/pg.rst @@ -460,9 +460,13 @@ The following configuration options are available: :default: YES :since: 3.9 - If set to "YES" (the default), the driver will try to use (and potentially - create) the ``ogr_system_tables.metadata`` table to retrieve and store - layer metadata. + If set to "YES" (the default), the driver will try to use the + ``ogr_system_tables.metadata`` table to retrieve and store + layer metadata. To be able to store metadata, the schema ``ogr_system_tables`` + and the event trigger ``ogr_system_tables_event_trigger_for_metadata`` must + already exist in the database, or the current user must have sufficient rights + (super-user rights for the event trigger) to be able to create them. If not, + a warning will be raised. - .. config:: OGR_PG_SKIP_CONFLICTS :choices: YES, NO diff --git a/doc/source/drivers/vector/pgeo.rst b/doc/source/drivers/vector/pgeo.rst index 2176296c7f42..f363b2feaead 100644 --- a/doc/source/drivers/vector/pgeo.rst +++ b/doc/source/drivers/vector/pgeo.rst @@ -104,8 +104,7 @@ How to use PGeo driver with unixODBC and MDB Tools (on Unix and Linux) This article gives step-by-step explanation of how to use OGR with unixODBC package and how to access Personal Geodatabase with PGeo -driver. See also `GDAL wiki for other -details `__ +driver. Prerequisites ~~~~~~~~~~~~~ diff --git a/doc/source/drivers/vector/shapefile.rst b/doc/source/drivers/vector/shapefile.rst index 67cd3abee67f..c978c611612b 100644 --- a/doc/source/drivers/vector/shapefile.rst +++ b/doc/source/drivers/vector/shapefile.rst @@ -166,9 +166,7 @@ terminated with an error. Note that this can make it very difficult to translate a mixed geometry layer from another format into Shapefile format using ogr2ogr, since ogr2ogr has no support for separating out geometries from a source -layer. See the -`FAQ `__ -for a solution. +layer. Shapefile feature attributes are stored in an associated .dbf file, and so attributes suffer a number of limitations: @@ -484,5 +482,3 @@ See Also -------- - `Shapelib Page `__ -- `User Notes on OGR Shapefile - Driver `__ diff --git a/doc/source/drivers/vector/sqlite.rst b/doc/source/drivers/vector/sqlite.rst index 0c005056843d..7242910c69c5 100644 --- a/doc/source/drivers/vector/sqlite.rst +++ b/doc/source/drivers/vector/sqlite.rst @@ -556,6 +556,17 @@ and optimize it. ogrinfo db.sqlite -sql "VACUUM" +Secure deletion +--------------- + +Depending on how SQLite3 is built, `secure deletion `__ +might or might not be enabled. +Starting with GDAL 3.10, secure deletion is always enabled, unless +``SECURE_DELETE`` is specified through the :config:`OGR_SQLITE_PRAGMA` +configuration option. +Note that secure deletion does not recover potential lost space, so running +a `VACUUM `__ query is recommended to fully +optimized a database that has been subject to updates or deletions. Example ------- diff --git a/doc/source/extra_path/robots.txt b/doc/source/extra_path/robots.txt new file mode 100644 index 000000000000..7eba37d690b6 --- /dev/null +++ b/doc/source/extra_path/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: /en/stable/ +Disallow: /en/ +Sitemap: https://gdal.org/sitemap.xml diff --git a/doc/source/faq.rst b/doc/source/faq.rst index d49c2f00bf77..b079349bd59d 100644 --- a/doc/source/faq.rst +++ b/doc/source/faq.rst @@ -4,7 +4,7 @@ FAQ ================================================================================ -.. TODO maybe migrate the chapters 2 and following of https://trac.osgeo.org/gdal/wiki/FAQ +.. TODO maybe migrate the chapters 2 and following of http://web.archive.org/web/https://trac.osgeo.org/gdal/wiki/FAQ .. only:: not latex @@ -61,7 +61,12 @@ You can use GDAL/OGR on all modern flavors of Unix: Linux, FreeBSD, Mac OS X; al Is there a graphical user interface to GDAL/OGR? ++++++++++++++++++++++++++++++++++++++++++++++++ -See :ref:`software_using_gdal`: +Plenty! Among the available options, `QGIS `__ is an excellent +free and open source application with a rich graphical user interface. It +allows users to display most GDAL raster and vector supported formats and +provides access to most GDAL utilities through its Processing toolbox. + +You can also consult the :ref:`list of software using GDAL `. .. toctree:: :hidden: @@ -92,6 +97,11 @@ Is GDAL thread-safe ? See :ref:`multithreading` +Does GDAL provide a Section 508 information? +++++++++++++++++++++++++++++++++++++++++++++ + +No, GDAL itself is an open-source software and project, not a Vendor. If your organization considers they need a `VPAT or Section 508 `_ form to be able to use GDAL, it is their responsibility to complete the needed steps themselves. + How do I cite GDAL ? ++++++++++++++++++++ diff --git a/doc/source/gdal_rtd/static/css/gdal.css b/doc/source/gdal_rtd/static/css/gdal.css index 6cedf6994ceb..964564335f44 100644 --- a/doc/source/gdal_rtd/static/css/gdal.css +++ b/doc/source/gdal_rtd/static/css/gdal.css @@ -203,12 +203,6 @@ a.reference.external::after text-decoration: none; } -/* Override wy-nav colors to match company branding */ -.wy-side-nav-search, .wy-side-nav-search img, .wy-nav .wy-menu-vertical header, .wy-nav-top, .wy-nav-top img -{ - background-color: #28728d; -} - /* center figures and captions */ .rst-content div.figure { text-align: center; } @@ -336,12 +330,20 @@ div.horizontal-logos::after { display: table; } +.wy-side-nav-search > div.switch-menus > div.version-switch { + background: white; + color: #343131; +} -/* background of logo area */ -div.wy-side-nav-search { - background: white +.wy-side-nav-search > div.switch-menus > div.version-switch select { + background: white; + color: #343131; } -.wy-side-nav-search > div.version { - color: #343131 +.wy-side-nav-search > div.switch-menus > div.version-switch select:active, +.wy-side-nav-search > div.switch-menus > div.version-switch select:focus, +.wy-side-nav-search > div.switch-menus > div.version-switch select:hover +{ + background: white; + color: #343131; } diff --git a/doc/source/index.rst b/doc/source/index.rst index bbfa8fd2c45f..9048d974ad77 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -21,6 +21,7 @@ GDAL contributing/index faq license + thanks Index ===== diff --git a/doc/source/index_pdf.rst b/doc/source/index_pdf.rst index 2466c5e73750..a5b61c259df1 100644 --- a/doc/source/index_pdf.rst +++ b/doc/source/index_pdf.rst @@ -21,3 +21,4 @@ GDAL community/index sponsors/index contributing/index + thanks diff --git a/doc/source/license.rst b/doc/source/license.rst index 6fd131833a8c..70b100272cd8 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -7,8 +7,7 @@ License License -------------------------------------------------------------------------------- -In general GDAL/OGR is licensed under an MIT style license with the -following terms: +In general, the GDAL/OGR source code is licensed under the MIT license, whose terms are: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +27,13 @@ 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. -The full licensing terms are available in the `LICENSE.TXT`_ file. +Some files are licensed under BSD 2-clause, BSD 3-clause or other non-copyleft +licenses. The full licensing terms are available in the `LICENSE.TXT`_ file. + +Note however that GDAL can be built against many dependencies, each of them with +their own licensing terms (possibly LGPL, GPL or proprietary), hence the use of +a GDAL binary can be subject to less permissive licensing terms than MIT, and it +is the responsibility of users to check that they comply with the overall +licensing terms. .. _`LICENSE.TXT`: https://raw.githubusercontent.com/OSGeo/gdal/master/LICENSE.TXT diff --git a/doc/source/programs/gdal2tiles.rst b/doc/source/programs/gdal2tiles.rst index 164e478aa9e6..1cc168df2cc9 100644 --- a/doc/source/programs/gdal2tiles.rst +++ b/doc/source/programs/gdal2tiles.rst @@ -298,22 +298,25 @@ The following configuration options are available to further customize the JPEG Examples -------- -Basic example: +.. example:: + :title: Basic example -.. code-block:: + .. code-block:: bash - gdal2tiles --zoom=2-5 input.tif output_folder + gdal2tiles --zoom=2-5 input.tif output_folder -MapML generation: +.. example:: + :title: MapML generation -.. code-block:: + .. code-block:: bash - gdal2tiles --zoom=16-18 -w mapml -p APSTILE --url "https://example.com" input.tif output_folder + gdal2tiles --zoom=16-18 -w mapml -p APSTILE --url "https://example.com" input.tif output_folder -MPI example: +.. example:: + :title: MPI example -.. code-block:: + .. code-block:: bash - mpiexec -n $NB_PROCESSES gdal2tiles --mpi --config GDAL_CACHEMAX 500 --zoom=2-5 input.tif output_folder + mpiexec -n $NB_PROCESSES gdal2tiles --mpi --config GDAL_CACHEMAX 500 --zoom=2-5 input.tif output_folder diff --git a/doc/source/programs/gdal2xyz.rst b/doc/source/programs/gdal2xyz.rst index f22fba52bc1c..cb948684daf7 100644 --- a/doc/source/programs/gdal2xyz.rst +++ b/doc/source/programs/gdal2xyz.rst @@ -99,15 +99,17 @@ The :program:`gdal2xyz` utility can be used to translate a raster file into xyz Examples -------- -:: +.. example:: - gdal2xyz -b 1 -b 2 -dstnodata 0 input.tif output.txt + .. code-block:: bash + gdal2xyz -b 1 -b 2 -dstnodata 0 input.tif output.txt -To create a text file in `xyz` format from the input file `input.tif`. -The first columns, x and y, are the coordinates of the centers of each cell. -The remaining columns represent the first and second bands. -We also replace the dataset nodata values with zeros. + + To create a text file in `xyz` format from the input file `input.tif`. + The first columns, x and y, are the coordinates of the centers of each cell. + The remaining columns represent the first and second bands. + We also replace the dataset nodata values with zeros. Caveats diff --git a/doc/source/programs/gdal_calc.rst b/doc/source/programs/gdal_calc.rst index 98527d1a1ebf..684d85e4c364 100644 --- a/doc/source/programs/gdal_calc.rst +++ b/doc/source/programs/gdal_calc.rst @@ -25,8 +25,8 @@ Synopsis Command line raster calculator with numpy syntax. Use any basic arithmetic supported by numpy arrays such as ``+``, ``-``, ``*``, and ``/`` along with logical operators such as ``>``. -Note that all files must have the same dimensions (unless extent option is used), -but no projection checking is performed (unless projectionCheck option is used). +Note that all files must have the same dimensions (unless the :option:`--extent` option is used), +but no projection checking is performed (unless the :option:`--projectionCheck` option is used). .. note:: @@ -37,17 +37,18 @@ but no projection checking is performed (unless projectionCheck option is used). .. option:: --calc= Calculation in numpy syntax using ``+``, ``-``, ``/``, ``*``, or any numpy array functions (i.e. ``log10()``). - Multiple ``--calc`` options can be listed to produce a multiband file (GDAL >= 3.2). + Multiple :option:`--calc` options can be listed to produce a multiband file (GDAL >= 3.2). + See :example:`gdal-calc-multiple-expr`. .. option:: -A - Input gdal raster file, you can use any letter (a-z, A-Z). (lower case supported since GDAL 3.3) + Input GDAL raster file, you can use any letter (a-z, A-Z). (lower case supported since GDAL 3.3) A letter may be repeated, or several values (separated by space) can be provided (GDAL >= 3.3). + The effect will be to create a 3D numpy array. Since GDAL 3.5, wildcard exceptions (using ?, \*) are supported for all shells/platforms. - The effect will be to create a 3-dim numpy array. - In such a case, the calculation formula must use this input as a 3-dim array and must return a 2D array (see examples below). - In case the calculation does not return a 2D array an error would be generated. + In such a case, the calculation formula must use this input as a 3D array and must return a 2D array (see :example:`gdal-calc-3d-sum`). + If the calculation does not return a 2D array an error will be generated. .. option:: --A_band= @@ -143,7 +144,9 @@ but no projection checking is performed (unless projectionCheck option is used). .. option:: --allBands=[a-z, A-Z] - Process all bands of given raster (a-z, A-Z). Requires a single calc for all bands. + Apply the expression to all bands of a given raster. When + :option:`--allBands` is used, :option:`--calc` may be specified only once. + See :example:`gdal-calc-allbands-1` and :example:`gdal-calc-allbands-2`. .. option:: --overwrite @@ -166,7 +169,7 @@ Python options .. versionadded:: 3.3 -The following options are available by using function the python interface of gdal_calc. +The following options are available by using the Python interface of :program:`gdal_calc`. They are not available using the command prompt. .. option:: user_namespace @@ -175,7 +178,7 @@ They are not available using the command prompt. .. option:: return_ds - If enabled, the output dataset would be returned from the function and not closed. + If enabled, the output dataset will be returned from the function and not closed. .. option:: color_table @@ -184,72 +187,109 @@ They are not available using the command prompt. Examples -------- -Add two files together: +.. example:: + :title: Average of two files -.. code-block:: bash + .. code-block:: bash - gdal_calc -A input1.tif -B input2.tif --outfile=result.tif --calc="A+B" + gdal_calc -A input1.tif -B input2.tif --outfile=result.tif --calc="(A+B)/2" -Average of two layers: + .. caution:: -.. code-block:: bash + If A and B inputs both have integer data types, integer division will be + performed. To avoid this, you can convert of one of the operands to a + floating point type before the division operation. - gdal_calc -A input1.tif -B input2.tif --outfile=result.tif --calc="(A+B)/2" + .. code-block:: bash -.. note:: + gdal_calc -A input.tif -B input2.tif --outfile=result.tif --calc="(A.astype(numpy.float64) + B) / 2" + +.. example:: + :title: Summing three files + + .. code-block:: bash + + gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="A+B+C" + +.. example:: + :title: Combining three files into a 3D array and summing + :id: gdal-calc-3d-sum + + .. code-block:: bash + + gdal_calc -A input1.tif -A input2.tif -A input3.tif --outfile=result.tif --calc="numpy.sum(A,axis=0)". - In the previous example, beware that if A and B inputs are of the same datatype, for example integers, you - may need to force the conversion of one of the operands before the division operation. +.. example:: + :title: Average of three files .. code-block:: bash - gdal_calc -A input.tif -B input2.tif --outfile=result.tif --calc="(A.astype(numpy.float64) + B) / 2" + gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="(A+B+C)/3" -Add three files together (two options with the same result): +.. example:: + :title: Average of three files, using 3D array -.. code-block:: bash + .. code-block:: bash + + gdal_calc -A input1.tif input2.tif input3.tif --outfile=result.tif --calc="numpy.average(a,axis=0)". + +.. example:: + :title: Maximum of three files + + .. code-block:: bash + + gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="numpy.max((A,B,C),axis=0)" - gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="A+B+C" +.. example:: + :title: Maximum of three files, using a 3D array -.. code-block:: bash + .. code-block:: bash - gdal_calc -A input1.tif -A input2.tif -A input3.tif --outfile=result.tif --calc="numpy.sum(A,axis=0)". + gdal_calc -A input1.tif input2.tif input3.tif --outfile=result.tif --calc="numpy.max(A,axis=0)" -Average of three layers (two options with the same result): +.. example:: + :title: Setting values of zero and below to NODATA -.. code-block:: bash + .. code-block:: bash - gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="(A+B+C)/3" + gdal_calc -A input.tif --outfile=result.tif --calc="A*(A>0)" --NoDataValue=0 -.. code-block:: bash +.. example:: + :title: Using logical operator to keep a range of values from input - gdal_calc -A input1.tif input2.tif input3.tif --outfile=result.tif --calc="numpy.average(a,axis=0)". + .. code-block:: bash -Maximum of three layers (two options with the same result): + gdal_calc -A input.tif --outfile=result.tif --calc="A*logical_and(A>100,A<150)" -.. code-block:: bash +.. example:: + :title: Performing two calculations and storing results in separate bands + :id: gdal-calc-multiple-expr - gdal_calc -A input1.tif -B input2.tif -C input3.tif --outfile=result.tif --calc="numpy.max((A,B,C),axis=0)" + .. code-block:: bash -.. code-block:: bash + gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 \ + --outfile=result.tif --calc="(A+B)/2" --calc="B*logical_and(A>100,A<150)" - gdal_calc -A input1.tif input2.tif input3.tif --outfile=result.tif --calc="numpy.max(A,axis=0)" +.. example:: + :title: Add a raster to each band in a 3-band raster + :id: gdal-calc-allbands-1 -Set values of zero and below to null: + .. code-block:: bash -.. code-block:: bash + gdal_calc -A 3band.tif -B 1band.tif --outfile result.tif --calc "A+B" --allBands A - gdal_calc -A input.tif --outfile=result.tif --calc="A*(A>0)" --NoDataValue=0 + The result will have three bands, where each band contains the values of ``1band.tif`` + added to the corresponding band in ``3band.tif``. -Using logical operator to keep a range of values from input: +.. example:: + :title: Add two three-band rasters + :id: gdal-calc-allbands-2 -.. code-block:: bash + .. code-block:: bash - gdal_calc -A input.tif --outfile=result.tif --calc="A*logical_and(A>100,A<150)" + gdal_calc -A 3band_a.tif -B 3band_b.tif --outfile result.tif --calc "A+B" --allBands A --allBands B -Work with multiple bands: + The result will have three bands, where each band contains the values of the corresponding + band of ``3band_a.tif`` added to the corresponding band of ``3band_b.tif``. -.. code-block:: bash - gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 \ - --outfile=result.tif --calc="(A+B)/2" --calc="B*logical_and(A>100,A<150)" diff --git a/doc/source/programs/gdal_contour.rst b/doc/source/programs/gdal_contour.rst index bf3440707c0c..40bcfa8134c5 100644 --- a/doc/source/programs/gdal_contour.rst +++ b/doc/source/programs/gdal_contour.rst @@ -142,13 +142,16 @@ C API Functionality of this utility can be done from C with :cpp:func:`GDALContourGenerate`. -Example -------- +Examples +-------- -This would create 10-meter contours from the DEM data in :file:`dem.tif` and -produce a shapefile in :file:`contour.shp|shx|dbf` with the contour elevations -in the ``elev`` attribute. +.. example:: + :title: Creating contours from a DEM -.. code-block:: + .. code-block:: + + gdal_contour -a elev dem.tif contour.shp -i 10.0 - gdal_contour -a elev dem.tif contour.shp -i 10.0 + This would create 10-meter contours from the DEM data in :file:`dem.tif` and + produce a shapefile in :file:`contour.shp|shx|dbf` with the contour elevations + in the ``elev`` attribute. diff --git a/doc/source/programs/gdal_create.rst b/doc/source/programs/gdal_create.rst index 57bc116b262e..784520f11509 100644 --- a/doc/source/programs/gdal_create.rst +++ b/doc/source/programs/gdal_create.rst @@ -102,24 +102,26 @@ like creating a PDF file from a XML composition file. Examples -------- -- Initialize a new GeoTIFF file with a uniform value of 10 +.. example:: + :title: Initialize a new GeoTIFF file with a uniform value of 10 - :: + .. code-block:: bash - gdal_create -outsize 20 20 -a_srs EPSG:4326 -a_ullr 2 50 3 49 -burn 10 out.tif + gdal_create -outsize 20 20 -a_srs EPSG:4326 -a_ullr 2 50 3 49 -burn 10 out.tif -- Create a PDF file from a XML composition file: +.. example:: + :title: Create a PDF file from a XML composition file - :: + .. code-block:: bash - gdal_create -co COMPOSITION_FILE=composition.xml out.pdf + gdal_create -co COMPOSITION_FILE=composition.xml out.pdf +.. example:: + :title: Initialize a blank GeoTIFF file from an input one -- Initialize a blank GeoTIFF file from an input one: + .. code-block:: bash - :: - - gdal_create -if prototype.tif output.tif + gdal_create -if prototype.tif output.tif diff --git a/doc/source/programs/gdal_edit.rst b/doc/source/programs/gdal_edit.rst index 983f315c478d..97aaedadd7e4 100644 --- a/doc/source/programs/gdal_edit.rst +++ b/doc/source/programs/gdal_edit.rst @@ -15,14 +15,14 @@ Synopsis .. code-block:: - gdal_edit [--help] [--help-general] [-ro] [-a_srs ] + gdal_edit [--help] [--help-general] [-ro] [-a_srs ] [-a_ullr ] [-a_ulurll ] [-tr ] [-unsetgt] [-unsetrpc] [-a_nodata ] [-unsetnodata] [-a_coord_epoch ] [-unsetepoch] [-unsetstats] [-stats] [-approx_stats] [-setstats ] [-scale ] [-offset ] [-units ] - [-colorinterp_ {red|green|blue|alpha|gray|undefined}]... + [-colorinterp_ {red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|swir|mwir|lwir|...}]... [-gcp []]... [-unsetmd] [-oo =]... [-mo =]... @@ -172,7 +172,7 @@ It works only with raster formats that support update access to existing dataset .. versionadded:: 3.1 -.. option:: -colorinterp_ {red|green|blue|alpha|gray|undefined} +.. option:: -colorinterp_ {red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|swir|mwir|lwir|...} Change the color interpretation of band X (where X is a valid band number, starting at 1). @@ -210,10 +210,18 @@ The :option:`-unsetstats` and either :option:`-stats` or :option:`-approx_stats` Example ------- -.. code-block:: +.. example:: + :title: Override the spatial bounds of a dataset and assign metadata values - gdal_edit -mo DATUM=WGS84 -mo PROJ=GEODETIC -a_ullr 7 47 8 46 test.ecw + .. code-block:: bash -.. code-block:: + gdal_edit -mo DATUM=WGS84 -mo PROJ=GEODETIC -a_ullr 7 47 8 46 test.ecw + +.. example:: + :title: Assign scale and offset values to dataset + + .. code-block:: bash + + gdal_edit -scale 1e3 1e4 -offset 0 10 twoBand.tif - gdal_edit -scale 1e3 1e4 -offset 0 10 twoBand.tif + The values in the GeoTIFF are not changed. diff --git a/doc/source/programs/gdal_footprint.rst b/doc/source/programs/gdal_footprint.rst index 5e4697ce8b85..241fb813e743 100644 --- a/doc/source/programs/gdal_footprint.rst +++ b/doc/source/programs/gdal_footprint.rst @@ -219,9 +219,12 @@ This utility is also callable from C with :cpp:func:`GDALFootprint`. Examples -------- -- Compute the footprint of a GeoTIFF file as a GeoJSON file using WGS 84 - longitude, latitude coordinates +.. example:: + :title: Compute the footprint of a GeoTIFF file as a GeoJSON file - :: + .. code-block:: bash - gdal_footprint -t_srs EPSG:4326 input.tif output.geojson + gdal_footprint -t_srs EPSG:4326 input.tif output.geojson + + The footprint will be written using WGS84 longitude, latitude coordinates, + regardless of the spatial reference system used by the input raster. diff --git a/doc/source/programs/gdal_grid.rst b/doc/source/programs/gdal_grid.rst index ba36c182b999..93b621a65789 100644 --- a/doc/source/programs/gdal_grid.rst +++ b/doc/source/programs/gdal_grid.rst @@ -505,24 +505,29 @@ This utility is also callable from C with :cpp:func:`GDALGrid`. Examples -------- -The following would create raster TIFF file from VRT datasource described in -`Reading comma separated values`_ section using the inverse distance to a power method. -Values to interpolate will be read from Z value of geometry record. +.. example:: + :title: Create a raster from a VRT datasource using inverse distance to a power -:: + .. code-block:: bash - gdal_grid -a invdist:power=2.0:smoothing=1.0 -txe 85000 89000 -tye 894000 890000 \ - -outsize 400 400 -of GTiff -ot Float64 -l dem dem.vrt dem.tiff + gdal_grid -a invdist:power=2.0:smoothing=1.0 -txe 85000 89000 -tye 894000 890000 \ + -outsize 400 400 -of GTiff -ot Float64 -l dem dem.vrt dem.tiff -The next command does the same thing as the previous one, but reads values to -interpolate from the attribute field specified with **-zfield** option -instead of geometry record. So in this case X and Y coordinates are being -taken from geometry and Z is being taken from the *"Elevation"* field. -The :config:`GDAL_NUM_THREADS` is also set to parallelize the computation. + This example creates a raster TIFF file from the VRT datasource described in + `Reading comma separated values`_ section using the inverse distance to a power method. + Values to interpolate will be read from Z value of geometry record. -:: +.. example:: + :title: Read values to interpolate from an attribute field + + .. code-block:: bash - gdal_grid -zfield "Elevation" -a invdist:power=2.0:smoothing=1.0 -txe 85000 89000 \ - -tye 894000 890000 -outsize 400 400 -of GTiff -ot Float64 -l dem dem.vrt \ - dem.tiff --config GDAL_NUM_THREADS ALL_CPUS + gdal_grid -zfield "Elevation" -a invdist:power=2.0:smoothing=1.0 -txe 85000 89000 \ + -tye 894000 890000 -outsize 400 400 -of GTiff -ot Float64 -l dem dem.vrt \ + dem.tiff --config GDAL_NUM_THREADS ALL_CPUS + This command does the same thing as the previous one, but reads values to + interpolate from the attribute field specified with **-zfield** option + instead of geometry record. So in this case X and Y coordinates are being + taken from geometry and Z is being taken from the *"Elevation"* field. + The :config:`GDAL_NUM_THREADS` is also set to parallelize the computation. diff --git a/doc/source/programs/gdal_merge.rst b/doc/source/programs/gdal_merge.rst index 2895eb857818..a5340fab8b4d 100644 --- a/doc/source/programs/gdal_merge.rst +++ b/doc/source/programs/gdal_merge.rst @@ -25,7 +25,7 @@ Synopsis Description ----------- -This utility will automatically mosaic a set of images. All the images must +This utility will automatically mosaic a set of images. All the images must be in the same coordinate system and have a matching number of bands, but they may be overlapping, and at different resolutions. In areas of overlap, the last image will be copied over earlier ones. Nodata/transparency values @@ -112,68 +112,67 @@ target pixel in the resulting raster nor will it overwrite a valid pixel value. Examples -------- -Creating an image with the pixels in all bands initialized to 255 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. example:: + :title: Creating an image with the pixels in all bands initialized to 255 -:: + .. code-block:: bash - gdal_merge -init 255 -o out.tif in1.tif in2.tif + gdal_merge -init 255 -o out.tif in1.tif in2.tif -Creating an RGB image that shows blue in pixels with no data -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. example:: + :title: Creating an RGB image that shows blue in pixels with no data -The first two bands will be initialized to 0 and the third band will be -initialized to 255. + .. code-block:: bash -:: + gdal_merge -init "0 0 255" -o out.tif in1.tif in2.tif - gdal_merge -init "0 0 255" -o out.tif in1.tif in2.tif + The first two bands will be initialized to 0 and the third band will be + initialized to 255. -Passing a large list of files to :program:`gdal_merge` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. example:: + :title: Passing a large list of files to :program:`gdal_merge` -A large list of files can be passed to :program:`gdal_merge` by -listing them in a text file using: + .. code-block:: bash -.. code-block:: bash + ls -1 *.tif > tiff_list.txt - ls -1 *.tif > tiff_list.txt + A large list of files can be passed to :program:`gdal_merge` by + listing them in a text file using the command above on Linux, or: -on Linux, or + .. code-block:: doscon -.. code-block:: doscon + dir /b /s *.tif > tiff_list.txt - dir /b /s *.tif > tiff_list.txt + on Windows. The text file can then be passed to :program:`gdal_merge` + using `--optfile`: -on Windows. The text file can then be passed to :program:`gdal_merge` -using `--optfile`: + .. code-block:: bash -:: + gdal_merge -o mosaic.tif --optfile tiff_list.txt - gdal_merge -o mosaic.tif --optfile tiff_list.txt -Creating an RGB image by merging 3 different greyscale bands -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. example:: + :title: Creating an RGB image by merging 3 different greyscale bands -Conduct "merging by stacking" with the :option:`-separate` flag. Given three -greyscale files that cover the same area, you can run: + Conduct "merging by stacking" with the :option:`-separate` flag. Given three + greyscale files that cover the same area, you can run: -.. code-block:: bash + .. code-block:: bash - gdal_merge -separate 1.tif 2.tif 3.tif -o rgb.tif + gdal_merge -separate 1.tif 2.tif 3.tif -o rgb.tif -This maps :file:`1.tif` to red, :file:`2.tif` to green and :file:`3.tif` to blue. + This maps :file:`1.tif` to red, :file:`2.tif` to green and :file:`3.tif` to blue. -Specifying overlap precedence -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The last image in the input line comes out on top of the finished image stack. -You might also need to use :option:`-n` to note which value should not be -copied into the destination image if it is not already defined as nodata. +.. example:: + :title: Specifying overlap precedence + The last image in the input line comes out on top of the finished image stack. + You might also need to use :option:`-n` to note which value should not be + copied into the destination image if it is not already defined as nodata. -.. code-block:: bash + .. code-block:: bash - gdal_merge -o merge.tif -n 0 image1.tif image2.tif image3.tif image4.tif + gdal_merge -o merge.tif -n 0 image1.tif image2.tif image3.tif image4.tif diff --git a/doc/source/programs/gdal_pansharpen.rst b/doc/source/programs/gdal_pansharpen.rst index 25cda6203690..a1f44d662546 100644 --- a/doc/source/programs/gdal_pansharpen.rst +++ b/doc/source/programs/gdal_pansharpen.rst @@ -113,33 +113,37 @@ Bands should be in the same projection. Example ------- -With spectral bands in a single dataset : +.. example:: + :title: With spectral bands in a single dataset -.. code-block:: + .. code-block:: - gdal_pansharpen panchro.tif multispectral.tif pansharpened_out.tif + gdal_pansharpen panchro.tif multispectral.tif pansharpened_out.tif -With a few spectral bands from a single dataset, reordered : +.. example:: + :title: With a few spectral bands from a single dataset, reordered -.. code-block:: + .. code-block:: - gdal_pansharpen panchro.tif multispectral.tif,band=3 multispectral.tif,band=2 multispectral.tif,band=1 pansharpened_out.tif + gdal_pansharpen panchro.tif multispectral.tif,band=3 multispectral.tif,band=2 multispectral.tif,band=1 pansharpened_out.tif -With spectral bands in several datasets : +.. example:: + :title: With spectral bands in several datasets -.. code-block:: + .. code-block:: - gdal_pansharpen panchro.tif band1.tif band2.tif band3.tif pansharpened_out.tif + gdal_pansharpen panchro.tif band1.tif band2.tif band3.tif pansharpened_out.tif -Specify weights: +.. example:: + :title: Specifying weights -.. code-block:: + .. code-block:: - gdal_pansharpen -w 0.7 -w 0.2 -w 0.1 panchro.tif multispectral.tif pansharpened_out.tif + gdal_pansharpen -w 0.7 -w 0.2 -w 0.1 panchro.tif multispectral.tif pansharpened_out.tif -Specify RGB bands from a RGBNir multispectral dataset while computing -the pseudo panchromatic intensity on the 4 RGBNir bands: +.. example:: + :title: Specify RGB bands from a RGBNir multispectral dataset while computing the pseudo panchromatic intensity on the 4 RGBNir bands -.. code-block:: + .. code-block:: - gdal_pansharpen -b 1 -b 2 -b 3 panchro.tif rgbnir.tif pansharpened_out.tif + gdal_pansharpen -b 1 -b 2 -b 3 panchro.tif rgbnir.tif pansharpened_out.tif diff --git a/doc/source/programs/gdal_rasterize.rst b/doc/source/programs/gdal_rasterize.rst index 048703557451..dd4def4e44ae 100644 --- a/doc/source/programs/gdal_rasterize.rst +++ b/doc/source/programs/gdal_rasterize.rst @@ -236,25 +236,30 @@ This utility is also callable from C with :cpp:func:`GDALRasterize`. Examples -------- -The following would burn all polygons from mask.shp into the RGB TIFF -file work.tif with the color red (RGB = 255,0,0). +.. example:: -.. code-block:: + The following would burn all polygons from :file:`mask.shp` into the RGB TIFF + file :file:`work.tif` with the color red (RGB = 255,0,0). - gdal_rasterize -b 1 -b 2 -b 3 -burn 255 -burn 0 -burn 0 -l mask mask.shp work.tif + .. code-block:: bash + gdal_rasterize -b 1 -b 2 -b 3 -burn 255 -burn 0 -burn 0 -l mask mask.shp work.tif -The following would burn all "class A" buildings into the output elevation -file, pulling the top elevation from the ROOF_H attribute. +.. example:: -.. code-block:: + The following would burn all "class A" buildings into the output elevation + file, pulling the top elevation from the ROOF_H attribute. - gdal_rasterize -a ROOF_H -where "class='A'" -l footprints footprints.shp city_dem.tif + .. code-block:: bash -The following would burn all polygons from footprint.shp into a new 1000x1000 -rgb TIFF as the color red. Note that :option:`-b` is not used; the order of the :option:`-burn` -options determines the bands of the output raster. + gdal_rasterize -a ROOF_H -where "class='A'" -l footprints footprints.shp city_dem.tif -.. code-block:: +.. example:: + + The following would burn all polygons from :file:`footprint.shp` into a new 1000x1000 + rgb TIFF as the color red. Note that :option:`-b` is not used; the order of the :option:`-burn` + options determines the bands of the output raster. + + .. code-block:: bash - gdal_rasterize -burn 255 -burn 0 -burn 0 -ot Byte -ts 1000 1000 -l footprints footprints.shp mask.tif + gdal_rasterize -burn 255 -burn 0 -burn 0 -ot Byte -ts 1000 1000 -l footprints footprints.shp mask.tif diff --git a/doc/source/programs/gdal_translate.rst b/doc/source/programs/gdal_translate.rst index 8c13b82d5e56..79a75d14cf36 100644 --- a/doc/source/programs/gdal_translate.rst +++ b/doc/source/programs/gdal_translate.rst @@ -32,8 +32,8 @@ Synopsis [-a_gt ] [-a_scale ] [-a_offset ] [-nogcp] [-gcp []]... - |-colorinterp{_bn} {red|green|blue|alpha|gray|undefined}] - |-colorinterp {red|green|blue|alpha|gray|undefined},...] + |-colorinterp{_bn} {red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|swir|mwir|lwir|...}] + |-colorinterp {red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|swir|mwir|lwir|...},...] [-mo =]... [-dmo "DOMAIN:META-TAG=VALUE"]... [-q] [-sds] [-co =]... [-stats] [-norat] [-noxmp] [-oo =]... @@ -156,23 +156,35 @@ resampling, and rescaling pixels in the process. formats that support serializing statistics computations (GeoTIFF, VRT...) Note that the values specified after :option:`-scale` are only used to compute a scale and offset to apply to the input raster values. In particular, ``src_min`` and - ``src_max`` are not used to clip input values. + ``src_max`` are not used to clip input values unless :option:`-exponent` + is also specified. + Instead of being clipped, source values that are outside the range of ``src_min`` and ``src_max`` will be scaled to values outside the range of ``dst_min`` and ``dst_max``. + If clipping without exponential scaling is desired, + ``-exponent 1`` can be used. :option:`-scale` can be repeated several times (if specified only once, it also applies to all bands of the output dataset), so as to specify per - band parameters. It is also possible to use the "-scale_bn" syntax where bn - is a band number (e.g. "-scale_2" for the 2nd band of the output dataset) + band parameters. It is also possible to use the ``-scale_bn`` syntax where bn + is a band number (e.g. ``-scale_2`` for the 2nd band of the output dataset) to specify the parameters of one or several specific bands. .. option:: -exponent - To apply non-linear scaling with a power function. exp_val is the exponent + Apply non-linear scaling with a power function. ``exp_val`` is the exponent of the power function (must be positive). This option must be used with the - -scale option. If specified only once, -exponent applies to all bands of + :option:`-scale` option. If specified only once, :option:`-exponent` applies + to all bands of the output image. It can be repeated several times so as to specify per - band parameters. It is also possible to use the "-exponent_bn" syntax where - bn is a band number (e.g. "-exponent_2" for the 2nd band of the output + band parameters. It is also possible to use the ``-exponent_bn`` syntax where + bn is a band number (e.g. ``-exponent_2`` for the 2nd band of the output dataset) to specify the parameters of one or several specific bands. + The scaled value ``Dst`` is calculated from the source value ``Src`` with the following + formula: + + .. math:: + {Dst} = \left( {Dst}_{max} - {Dst}_{min} \right) \times \operatorname{max} \left( 0, \operatorname{min} \left( 1, \left( \frac{{Src} - {Src}_{min}}{{Src}_{max}-{Src}_{min}} \right)^{exp\_val} \right) \right) + {Dst}_{min} + + .. option:: -unscale Apply the scale/offset metadata for the bands to convert scaled values to @@ -289,14 +301,14 @@ resampling, and rescaling pixels in the process. nodata value, this does not cause pixel values that are equal to that nodata value to be changed to the value specified with this option. -.. option:: -colorinterp_X +.. option:: -colorinterp_X Override the color interpretation of band X (where X is a valid band number, starting at 1) .. versionadded:: 2.3 -.. option:: -colorinterp {red|green|blue|alpha|gray|undefined},... +.. option:: -colorinterp {red|green|blue|alpha|gray|undefined|pan|coastal|rededge|nir|swir|mwir|lwir|...},... Override the color interpretation of all specified bands. For example -colorinterp red,green,blue,alpha for a 4 band output dataset. @@ -434,28 +446,34 @@ This utility is also callable from C with :cpp:func:`GDALTranslate`. Examples -------- -:: +.. example:: + :title: Creating a tiled GeoTIFF + + .. code-block:: bash - gdal_translate -of GTiff -co "TILED=YES" utm.tif utm_tiled.tif + gdal_translate -of GTiff -co "TILED=YES" utm.tif utm_tiled.tif -To create a JPEG-compressed TIFF with internal mask from a RGBA dataset +.. example:: + :title: Creating a JPEG-compressed TIFF with internal mask from a RGBA dataset -:: + .. code-block:: bash - gdal_translate rgba.tif withmask.tif -b 1 -b 2 -b 3 -mask 4 -co COMPRESS=JPEG \ - -co PHOTOMETRIC=YCBCR --config GDAL_TIFF_INTERNAL_MASK YES + gdal_translate rgba.tif withmask.tif -b 1 -b 2 -b 3 -mask 4 -co COMPRESS=JPEG \ + -co PHOTOMETRIC=YCBCR --config GDAL_TIFF_INTERNAL_MASK YES -To create a RGBA dataset from a RGB dataset with a mask +.. example:: + :title: Creating a RGBA dataset from a RGB dataset with a mask -:: + .. code-block:: bash - gdal_translate withmask.tif rgba.tif -b 1 -b 2 -b 3 -b mask + gdal_translate withmask.tif rgba.tif -b 1 -b 2 -b 3 -b mask -Subsetting using :option:`-projwin` and :option:`-outsize`: +.. example:: + :title: Subsetting using :option:`-projwin` and :option:`-outsize` -.. code-block:: bash + .. code-block:: bash - gdal_translate -projwin -20037500 10037500 0 0 -outsize 100 100 frmt_wms_googlemaps_tms.xml junk.png + gdal_translate -projwin -20037500 10037500 0 0 -outsize 100 100 frmt_wms_googlemaps_tms.xml junk.png diff --git a/doc/source/programs/gdal_viewshed.rst b/doc/source/programs/gdal_viewshed.rst index 26034a29288b..365ad0fdb017 100644 --- a/doc/source/programs/gdal_viewshed.rst +++ b/doc/source/programs/gdal_viewshed.rst @@ -173,22 +173,24 @@ C API Functionality of this utility can be done from C with :cpp:func:`GDALViewshedGenerate`. -Example -------- +Examples +-------- + +.. example:: -Screenshot of 2 combined viewshed analysis, with the yellow pixels showing the area that is -visible from the both observation locations (the green dots), while the small green area is -only visible from one location. + Screenshot of 2 combined viewshed analysis, with the yellow pixels showing the area that is + visible from the both observation locations (the green dots), while the small green area is + only visible from one location. -.. figure:: ../../images/gdal_viewshed.png + .. figure:: ../../images/gdal_viewshed.png -Create a viewshed raster with a radius of 500 for a person standing at location (-10147017, 5108065). + Create a viewshed raster with a radius of 500 for a person standing at location (-10147017, 5108065). -.. code-block:: bash + .. code-block:: bash - gdal_viewshed -md 500 -ox -10147017 -oy 5108065 source.tif destination.tif + gdal_viewshed -md 500 -ox -10147017 -oy 5108065 source.tif destination.tif Reference --------- diff --git a/doc/source/programs/gdaladdo.rst b/doc/source/programs/gdaladdo.rst index d24b6d06ea5b..41686cbeccc2 100644 --- a/doc/source/programs/gdaladdo.rst +++ b/doc/source/programs/gdaladdo.rst @@ -103,7 +103,7 @@ most supported file formats with one of several downsampling algorithms. and regenerate the overview for areas corresponding to sources whose timestamp is more recent than the external overview of the VRT. By default all existing overview levels will be refreshed, unless explicit - levels are specified. + levels are specified. See :example:`refresh-vrt`. .. option:: --partial-refresh-from-projwin @@ -126,7 +126,7 @@ most supported file formats with one of several downsampling algorithms. Note that the filenames are only used to determine the regions of interest to refresh. The reference source pixels are the one of the main dataset. By default all existing overview levels will be refreshed, unless explicit - levels are specified. + levels are specified. See :example:`refresh-tiff`. .. option:: @@ -168,7 +168,7 @@ in TIFF format. By default, the GeoTIFF driver stores overviews internally to t operated on (if it is writable), unless the -ro flag is specified. Most drivers also support an alternate overview format using Erdas Imagine -format. To trigger this use the :config:`USE_RRD=YES` configuration option. This will +format. To trigger this use the :config:`USE_RRD=YES` configuration option (:example:`use-rrd`). This will place the overviews in an associated .aux file suitable for direct use with Imagine or ArcGIS as well as GDAL applications. (e.g. --config USE_RRD YES) @@ -280,64 +280,78 @@ Functionality of this utility can be done from C with :cpp:func:`GDALBuildOvervi Examples -------- -Create overviews, embedded in the supplied TIFF file, with automatic computation -of levels (GDAL 2.3 or later) +.. example:: + :title: Create overviews, embedded in the supplied TIFF file, with automatic computation of levels -:: + .. code-block:: bash - gdaladdo -r average abc.tif + gdaladdo -r average abc.tif -Create overviews, embedded in the supplied TIFF file: +.. example:: + :title: Create overviews, embedded in the supplied TIFF file -:: + .. code-block:: bash - gdaladdo -r average abc.tif 2 4 8 16 + gdaladdo -r average abc.tif 2 4 8 16 -Create an external compressed GeoTIFF overview file from the ERDAS .IMG file: +.. example:: + :title: Create an external compressed GeoTIFF overview file from the ERDAS .IMG file -:: + .. code-block:: bash - gdaladdo -ro --config COMPRESS_OVERVIEW DEFLATE erdas.img 2 4 8 16 + gdaladdo -ro --config COMPRESS_OVERVIEW DEFLATE erdas.img 2 4 8 16 -Create an external JPEG-compressed GeoTIFF overview file from a 3-band RGB dataset -(if the dataset is a writable GeoTIFF, you also need to add the -ro option to -force the generation of external overview): +.. example:: + :title: Create an external JPEG-compressed GeoTIFF overview file from a 3-band RGB dataset -:: + If the dataset is a writable GeoTIFF, you also need to add the :option:`-ro` option to + force the generation of external overview. - gdaladdo --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR - --config INTERLEAVE_OVERVIEW PIXEL rgb_dataset.ext 2 4 8 16 + .. code-block:: bash -Create an Erdas Imagine format overviews for the indicated JPEG file: + gdaladdo --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR + --config INTERLEAVE_OVERVIEW PIXEL rgb_dataset.ext 2 4 8 16 -:: +.. example:: + :title: Create Erdas Imagine format overviews for the indicated JPEG file + :id: use-rrd - gdaladdo --config USE_RRD YES airphoto.jpg 3 9 27 81 + .. code-block:: bash -Create overviews for a specific subdataset, like for example one of potentially many raster layers in a GeoPackage (the "filename" parameter must be driver prefix, filename and subdataset name, like e.g. shown by gdalinfo): + gdaladdo --config USE_RRD YES airphoto.jpg 3 9 27 81 -:: +.. example:: + :title: Create overviews for a specific subdataset - gdaladdo GPKG:file.gpkg:layer + For example, one of potentially many raster layers in a GeoPackage (the "filename" parameter must be driver prefix, filename and subdataset name, like e.g. shown by gdalinfo): + .. code-block:: bash -Refresh overviews of a VRT file, for sources that have been modified after the -.vrt.ovr generation: + gdaladdo GPKG:file.gpkg:layer -:: - gdalbuildvrt my.vrt tile1.tif tile2.tif # create VRT - gdaladdo -r cubic my.vrt # initial overview generation - touch tile1.tif # simulate update of one of the source tiles - gdaladdo --partial-refresh-from-source-timestamp -r cubic my.vrt # refresh overviews +.. example:: + :title: Refresh overviews of a VRT file + :id: refresh-vrt + This is needed when for sources have been modified after the .vrt.ovr generation: -Refresh overviews of a TIFF file: + .. code-block:: bash -:: + gdalbuildvrt my.vrt tile1.tif tile2.tif # create VRT + gdaladdo -r cubic my.vrt # initial overview generation + touch tile1.tif # simulate update of one of the source tiles + gdaladdo --partial-refresh-from-source-timestamp -r cubic my.vrt # refresh overviews + + +.. example:: + :title: Refresh overviews of a TIFF file + :id: refresh-tiff + + .. code-block:: bash - gdalwarp -overwrite tile1.tif tile2.tif mosaic.tif # create mosaic - gdaladdo -r cubic mosaic.tif # initial overview generation - touch tile1.tif # simulate update of one of the source tiles - gdalwarp tile1.tif mosaic.tif # update mosaic - gdaladdo --partial-refresh-from-source-extent tile1.tif -r cubic my.vrt # refresh overviews + gdalwarp -overwrite tile1.tif tile2.tif mosaic.tif # create mosaic + gdaladdo -r cubic mosaic.tif # initial overview generation + touch tile1.tif # simulate update of one of the source tiles + gdalwarp tile1.tif mosaic.tif # update mosaic + gdaladdo --partial-refresh-from-source-extent tile1.tif -r cubic my.vrt # refresh overviews diff --git a/doc/source/programs/gdalbuildvrt.rst b/doc/source/programs/gdalbuildvrt.rst index efeba4c381c8..90a980305b7d 100644 --- a/doc/source/programs/gdalbuildvrt.rst +++ b/doc/source/programs/gdalbuildvrt.rst @@ -28,6 +28,7 @@ Synopsis [-a_srs ] [-r {nearest|bilinear|cubic|cubicspline|lanczos|average|mode}] [-oo =]... + [-co =]... [-input_file_list ] [-overwrite] [-strict | -non_strict] []... @@ -172,14 +173,15 @@ changed in later versions. Set nodata values at the VRT band level (different values can be supplied for each band). If more than one value is supplied all values should be quoted to keep them together - as a single operating system argument. If the option is not specified, + as a single operating system argument (:example:`vrtnodata`). If the option is not specified, intrinsic nodata settings on the first dataset will be used (if they exist). The value set by this option is written in the NoDataValue element of each VRTRasterBand element. Use a value of `None` to ignore intrinsic nodata settings on the source datasets. .. option:: -separate - Place each input file into a separate band. Contrary to the default mode, it is not + Place each input file into a separate band. See :example:`separate`. + Contrary to the default mode, it is not required that all bands have the same datatype. Starting with GDAL 3.8, all bands of each input file are added as separate @@ -208,9 +210,15 @@ changed in later versions. .. versionadded:: 2.2 +.. option:: -co = + + Specify a :ref:`VRT driver creation option `. + + .. versionadded:: 3.10 + .. option:: -input_file_list - To specify a text file with an input filename on each line + To specify a text file with an input filename on each line. See :example:`filelist`. .. option:: -q @@ -235,30 +243,36 @@ changed in later versions. Examples -------- -- Make a virtual mosaic from all TIFF files contained in a directory : +.. example:: + :title: Make a virtual mosaic from all TIFF files contained in a directory -:: + .. code-block:: bash - gdalbuildvrt doq_index.vrt doq/*.tif + gdalbuildvrt doq_index.vrt doq/*.tif -- Make a virtual mosaic from files whose name is specified in a text file : +.. example:: + :title: Make a virtual mosaic from files whose name is specified in a text file + :id: filelist -:: + .. code-block:: bash gdalbuildvrt -input_file_list my_list.txt doq_index.vrt +.. example:: + :title: Make a RGB virtual mosaic from 3 single-band input files + :id: separate -- Make a RGB virtual mosaic from 3 single-band input files : - -:: + .. code-block:: bash - gdalbuildvrt -separate rgb.vrt red.tif green.tif blue.tif + gdalbuildvrt -separate rgb.vrt red.tif green.tif blue.tif -- Make a virtual mosaic with blue background colour (RGB: 0 0 255) : +.. example:: + :title: Make a virtual mosaic with blue background colour (RGB: 0 0 255) + :id: vrtnodata -:: + .. code-block:: bash - gdalbuildvrt -hidenodata -vrtnodata "0 0 255" doq_index.vrt doq/*.tif + gdalbuildvrt -hidenodata -vrtnodata "0 0 255" doq_index.vrt doq/*.tif C API ----- diff --git a/doc/source/programs/gdaldem.rst b/doc/source/programs/gdaldem.rst index db0d73cb7b18..f30d63d445c2 100644 --- a/doc/source/programs/gdaldem.rst +++ b/doc/source/programs/gdaldem.rst @@ -56,7 +56,7 @@ Generate a color relief map: [-alpha] [-exact_color_entry | -nearest_color_entry] [-b ] [-of format] [-co =]... [-q] - where color_text_file contains lines of the format "elevation_value red green blue [alpha]". If alpha column is present it can be enabled for use with '-alpha'. + where color_text_file contains lines of the format "elevation_value red green blue [alpha]". If alpha column is present it can be enabled for use with '-alpha'. Generate a Terrain Ruggedness Index (TRI) map: @@ -413,8 +413,8 @@ See also Documentation of related GRASS utilities: -https://grass.osgeo.org/grass79/manuals/r.slope.aspect.html +https://grass.osgeo.org/grass84/manuals/r.slope.aspect.html -https://grass.osgeo.org/grass79/manuals/r.relief.html +https://grass.osgeo.org/grass84/manuals/r.relief.html -https://grass.osgeo.org/grass79/manuals/r.colors.html +https://grass.osgeo.org/grass84/manuals/r.colors.html diff --git a/doc/source/programs/gdalenhance.rst b/doc/source/programs/gdalenhance.rst new file mode 100644 index 000000000000..e9896cfebcf8 --- /dev/null +++ b/doc/source/programs/gdalenhance.rst @@ -0,0 +1,97 @@ +.. _gdalenhance: + +================================================================================ +gdalenhance +================================================================================ + +.. only:: html + + Enhance the contrast of raster images using histogram equalization. + +.. Index:: gdalenhance + +Synopsis +-------- + +.. code-block:: + + gdalenhance [--help-general] + [-of format] [-co "NAME=VALUE"]* + [-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/ + CInt16/CInt32/CFloat32/CFloat64}] + [-equalize] + [-config filename] + [] + +Description +----------- + +The :program:`gdalenhance` utility enhances the contrast of raster images using +histogram equalization. It can either generate a LUT (look-up-table) that can +later be applied to enhance contrast, or it can write the enhanced image +directly. + +.. figure:: ../../images/programs/gdalenhance_little_spruce.jpg + + Original image. + +.. figure:: ../../images/programs/gdalenhance_little_spruce_enhanced.jpg + + Image after histogram equalization using :program:`gdalenhance`. + + +.. program:: gdalenhance + +.. include:: options/help_and_help_general.rst + +.. option:: -of format + + Select the output format. The default is GeoTIFF (GTiff). + +.. include:: options/co.rst + +.. include:: options/ot.rst + +.. option:: -equalize + + Get source image histogram and compute equalization LUTs from + it. + +.. option:: -config + + Apply a specified LUT to enhance the contrast of the image. + The number of lines in the LUT file should be equal to the number of bands + of the images. + Example of LUT file: + + .. code-block:: + + 1:Band -0.5:ScaleMin 255.5:ScaleMax 0 0 8 16 16 17 17 17 17 18 18 18 18 18 18 19 19 19 19 20 20 20 21 21 21 22 22 22 23 23 24 24 25 25 26 27 27 28 29 30 30 31 32 33 34 35 36 37 38 39 40 42 43 44 46 47 48 50 51 53 55 56 58 60 62 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131 133 135 137 138 140 142 144 146 148 150 152 153 155 157 159 161 162 164 166 168 169 171 173 174 176 178 179 181 182 184 186 187 189 190 192 193 195 196 198 199 200 202 203 205 206 207 208 210 211 212 213 214 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 234 235 236 237 238 239 239 240 241 241 242 243 244 244 245 245 246 246 247 247 248 248 249 249 250 250 250 251 251 251 251 251 252 252 252 252 252 252 252 252 252 252 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 254 254 254 254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 + 2:Band -0.5:ScaleMin 255.5:ScaleMax 0 0 8 16 16 16 17 17 17 17 17 17 17 17 17 18 18 18 18 18 18 19 19 19 19 19 20 20 20 20 21 21 22 22 23 23 24 24 25 26 27 27 28 29 30 31 32 33 34 35 36 37 38 39 41 42 43 45 46 47 49 51 52 54 55 57 59 60 62 64 66 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 157 159 161 163 165 166 168 170 172 173 175 177 179 180 182 183 185 187 188 190 191 193 194 196 197 199 200 202 203 204 206 207 208 209 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 230 231 232 233 234 235 235 236 237 238 239 239 240 241 241 242 243 243 244 245 245 246 246 247 247 248 248 248 249 249 250 250 250 250 251 251 251 251 252 252 252 252 252 252 252 252 252 252 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 254 254 254 254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 + 3:Band -0.5:ScaleMin 255.5:ScaleMax 0 0 9 17 17 18 18 18 18 18 19 19 19 19 19 19 20 20 20 20 20 20 21 21 21 21 21 21 22 22 22 22 22 23 23 23 24 24 24 25 25 26 26 27 28 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 45 46 47 48 50 51 53 54 56 57 59 60 62 63 65 67 69 70 72 74 76 78 80 82 84 86 88 90 92 94 97 99 101 103 105 107 109 111 113 115 116 118 120 122 124 126 127 129 131 133 134 136 138 139 141 143 144 146 147 149 151 152 154 155 157 159 160 162 163 165 167 168 170 171 173 175 176 178 179 181 182 184 186 187 189 190 192 193 195 197 198 200 201 203 204 206 207 209 210 212 213 214 216 217 218 219 220 222 223 224 225 226 227 228 229 230 231 232 233 233 234 235 236 237 238 239 239 240 241 242 243 243 244 245 246 246 247 247 248 248 249 249 250 250 251 251 251 251 252 252 252 252 252 252 252 252 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 254 254 255 255 255 255 255 255 2550 + +Examples +-------- + +.. example:: + :title: Apply equalization histogram to enhance the contrast of the image + + .. code-block:: + + gdalenhance -equalize rgb.tif rgb_equalize_enhance.tif + +.. example:: + :title: Write an equalization LUT to the console + + .. code-block:: + + gdalenhance -equalize rgb.tif + +.. example:: + :title: Apply a custom LUT (look up-table) to enhance the contrast of the image + + .. code-block:: + + gdalenhance -config enhance_config rgb.tif rgb_custom_enhance.tif + + diff --git a/doc/source/programs/gdalinfo.rst b/doc/source/programs/gdalinfo.rst index 01ef40ad0d97..6ccef3d6593a 100644 --- a/doc/source/programs/gdalinfo.rst +++ b/doc/source/programs/gdalinfo.rst @@ -181,289 +181,22 @@ This utility is also callable from C with :cpp:func:`GDALInfo`. .. versionadded:: 2.1 -Example -------- +Examples +-------- -.. code-block:: +.. example:: + :title: Default output format + + .. command-output:: gdalinfo utmsmall.tif + :cwd: ../../../autotest/gcore/data + +.. example:: + :title: JSON output + + For corner coordinates formatted as decimal degree instead of the above degree, minute, second, inspect the ``wgs84Extent`` member of ``gdalinfo -json``: + + Example of JSON output with ``gdalinfo -json utmsmall.tif``: - gdalinfo ~/openev/utm.tif - Driver: GTiff/GeoTIFF - Size is 512, 512 - Coordinate System is: - PROJCS["NAD27 / UTM zone 11N", - GEOGCS["NAD27", - DATUM["North_American_Datum_1927", - SPHEROID["Clarke 1866",6378206.4,294.978698213901]], - PRIMEM["Greenwich",0], - UNIT["degree",0.0174532925199433]], - PROJECTION["Transverse_Mercator"], - PARAMETER["latitude_of_origin",0], - PARAMETER["central_meridian",-117], - PARAMETER["scale_factor",0.9996], - PARAMETER["false_easting",500000], - PARAMETER["false_northing",0], - UNIT["metre",1]] - Origin = (440720.000000,3751320.000000) - Pixel Size = (60.000000,-60.000000) - Corner Coordinates: - Upper Left ( 440720.000, 3751320.000) (117d38'28.21"W, 33d54'8.47"N) - Lower Left ( 440720.000, 3720600.000) (117d38'20.79"W, 33d37'31.04"N) - Upper Right ( 471440.000, 3751320.000) (117d18'32.07"W, 33d54'13.08"N) - Lower Right ( 471440.000, 3720600.000) (117d18'28.50"W, 33d37'35.61"N) - Center ( 456080.000, 3735960.000) (117d28'27.39"W, 33d45'52.46"N) - Band 1 Block=512x16 Type=Byte, ColorInterp=Gray - -For corner coordinates formatted as decimal degree instead of the above degree, minute, second, inspect the ``wgs84Extent`` member of gdalinfo -json: - -Example of JSON output with ``gdalinfo -json byte.tif`` - -.. code-block:: json - - { - "description":"byte.tif", - "driverShortName":"GTiff", - "driverLongName":"GeoTIFF", - "files":[ - "byte.tif" - ], - "size":[ - 20, - 20 - ], - "coordinateSystem":{ - "wkt":"PROJCRS[\"NAD27 / UTM zone 11N\",\n BASEGEOGCRS[\"NAD27\",\n DATUM[\"North American Datum 1927\",\n ELLIPSOID[\"Clarke 1866\",6378206.4,294.978698213898,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4267]],\n CONVERSION[\"UTM zone 11N\",\n METHOD[\"Transverse Mercator\",\n ID[\"EPSG\",9807]],\n PARAMETER[\"Latitude of natural origin\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8801]],\n PARAMETER[\"Longitude of natural origin\",-117,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"Scale factor at natural origin\",0.9996,\n SCALEUNIT[\"unity\",1],\n ID[\"EPSG\",8805]],\n PARAMETER[\"False easting\",500000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"(E)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"(N)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Engineering survey, topographic mapping.\"],\n AREA[\"North America - between 120°W and 114°W - onshore. Canada - Alberta; British Columbia; Northwest Territories; Nunavut. Mexico. United States (USA) - California; Idaho; Nevada; Oregon; Washington.\"],\n BBOX[26.93,-120,78.13,-114]],\n ID[\"EPSG\",26711]]", - "dataAxisToSRSAxisMapping":[ - 1, - 2 - ] - }, - "geoTransform":[ - 440720.0, - 60.0, - 0.0, - 3751320.0, - 0.0, - -60.0 - ], - "metadata":{ - "":{ - "AREA_OR_POINT":"Area" - }, - "IMAGE_STRUCTURE":{ - "INTERLEAVE":"BAND" - } - }, - "cornerCoordinates":{ - "upperLeft":[ - 440720.0, - 3751320.0 - ], - "lowerLeft":[ - 440720.0, - 3750120.0 - ], - "lowerRight":[ - 441920.0, - 3750120.0 - ], - "upperRight":[ - 441920.0, - 3751320.0 - ], - "center":[ - 441320.0, - 3750720.0 - ] - }, - "wgs84Extent":{ - "type":"Polygon", - "coordinates":[ - [ - [ - -117.6420428, - 33.9023684 - ], - [ - -117.6419617, - 33.8915461 - ], - [ - -117.6289846, - 33.8916131 - ], - [ - -117.629064, - 33.9024353 - ], - [ - -117.6420428, - 33.9023684 - ] - ] - ] - }, - "bands":[ - { - "band":1, - "block":[ - 20, - 20 - ], - "type":"Byte", - "colorInterpretation":"Gray", - "metadata":{ - } - } - ], - "stac":{ - "proj:shape":[ - 20, - 20 - ], - "proj:wkt2":"PROJCRS[\"NAD27 / UTM zone 11N\",\n BASEGEOGCRS[\"NAD27\",\n DATUM[\"North American Datum 1927\",\n ELLIPSOID[\"Clarke 1866\",6378206.4,294.978698213898,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4267]],\n CONVERSION[\"UTM zone 11N\",\n METHOD[\"Transverse Mercator\",\n ID[\"EPSG\",9807]],\n PARAMETER[\"Latitude of natural origin\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8801]],\n PARAMETER[\"Longitude of natural origin\",-117,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"Scale factor at natural origin\",0.9996,\n SCALEUNIT[\"unity\",1],\n ID[\"EPSG\",8805]],\n PARAMETER[\"False easting\",500000,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"(E)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"(N)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Engineering survey, topographic mapping.\"],\n AREA[\"North America - between 120°W and 114°W - onshore. Canada - Alberta; British Columbia; Northwest Territories; Nunavut. Mexico. United States (USA) - California; Idaho; Nevada; Oregon; Washington.\"],\n BBOX[26.93,-120,78.13,-114]],\n ID[\"EPSG\",26711]]", - "proj:epsg":26711, - "proj:projjson":{ - "$schema":"https://proj.org/schemas/v0.6/projjson.schema.json", - "type":"ProjectedCRS", - "name":"NAD27 / UTM zone 11N", - "base_crs":{ - "name":"NAD27", - "datum":{ - "type":"GeodeticReferenceFrame", - "name":"North American Datum 1927", - "ellipsoid":{ - "name":"Clarke 1866", - "semi_major_axis":6378206.4, - "semi_minor_axis":6356583.8 - } - }, - "coordinate_system":{ - "subtype":"ellipsoidal", - "axis":[ - { - "name":"Geodetic latitude", - "abbreviation":"Lat", - "direction":"north", - "unit":"degree" - }, - { - "name":"Geodetic longitude", - "abbreviation":"Lon", - "direction":"east", - "unit":"degree" - } - ] - }, - "id":{ - "authority":"EPSG", - "code":4267 - } - }, - "conversion":{ - "name":"UTM zone 11N", - "method":{ - "name":"Transverse Mercator", - "id":{ - "authority":"EPSG", - "code":9807 - } - }, - "parameters":[ - { - "name":"Latitude of natural origin", - "value":0, - "unit":"degree", - "id":{ - "authority":"EPSG", - "code":8801 - } - }, - { - "name":"Longitude of natural origin", - "value":-117, - "unit":"degree", - "id":{ - "authority":"EPSG", - "code":8802 - } - }, - { - "name":"Scale factor at natural origin", - "value":0.9996, - "unit":"unity", - "id":{ - "authority":"EPSG", - "code":8805 - } - }, - { - "name":"False easting", - "value":500000, - "unit":"metre", - "id":{ - "authority":"EPSG", - "code":8806 - } - }, - { - "name":"False northing", - "value":0, - "unit":"metre", - "id":{ - "authority":"EPSG", - "code":8807 - } - } - ] - }, - "coordinate_system":{ - "subtype":"Cartesian", - "axis":[ - { - "name":"Easting", - "abbreviation":"E", - "direction":"east", - "unit":"metre" - }, - { - "name":"Northing", - "abbreviation":"N", - "direction":"north", - "unit":"metre" - } - ] - }, - "scope":"Engineering survey, topographic mapping.", - "area":"North America - between 120°W and 114°W - onshore. Canada - Alberta; British Columbia; Northwest Territories; Nunavut. Mexico. United States (USA) - California; Idaho; Nevada; Oregon; Washington.", - "bbox":{ - "south_latitude":26.93, - "west_longitude":-120, - "north_latitude":78.13, - "east_longitude":-114 - }, - "id":{ - "authority":"EPSG", - "code":26711 - } - }, - "proj:transform":[ - 440720.0, - 60.0, - 0.0, - 3751320.0, - 0.0, - -60.0 - ], - "raster:bands":[ - { - "data_type":"uint8" - } - ], - "eo:bands":[ - { - "name":"b1", - "description":"Gray" - } - ] - } - } + .. program-output:: gdalinfo -json utmsmall.tif + :cwd: ../../../autotest/gcore/data + :language: json diff --git a/doc/source/programs/gdallocationinfo.rst b/doc/source/programs/gdallocationinfo.rst index a0188f8f10e0..c89f5740fd6c 100644 --- a/doc/source/programs/gdallocationinfo.rst +++ b/doc/source/programs/gdallocationinfo.rst @@ -38,6 +38,7 @@ reporting options are provided. .. option:: -xml The output report will be XML formatted for convenient post processing. + (:example:`xml`). .. option:: -lifonly @@ -164,54 +165,59 @@ gdallocationinfo in the future. Examples -------- -Simple example reporting on pixel (256,256) on the file utm.tif. - -:: - - $ gdallocationinfo utm.tif 256 256 - Report: - Location: (256P,256L) - Band 1: - Value: 115 - -Query a VRT file providing the location in WGS84, and getting the result in xml. - -:: - - $ gdallocationinfo -xml -wgs84 utm.vrt -117.5 33.75 - - - - utm.tif - - 16 - - - -Reading location from stdin. - -:: - - $ cat coordinates.txt - 443020 3748359 - 441197 3749005 - 443852 3747743 - - $ cat coordinates.txt | gdallocationinfo -geoloc utmsmall.tif - Report: - Location: (38P,49L) - Band 1: - Value: 214 - Report: - Location: (7P,38L) - Band 1: - Value: 107 - Report: - Location: (52P,59L) - Band 1: - Value: 148 - - $ cat coordinates.txt | gdallocationinfo -geoloc -valonly -E -field_sep , utmsmall.tif - 443020,3748359,214 - 441197,3749005,107 - 443852,3747743,148 +.. example:: + :title: Reporting on pixel (256,256) on the file :file:`utm.tif` + + .. code-block:: console + + $ gdallocationinfo utm.tif 256 256 + Report: + Location: (256P,256L) + Band 1: + Value: 115 + + +.. example:: + :title: Querying a VRT file providing the location in WGS84, and getting the result in XML + :id: xml + + .. code-block:: console + + $ gdallocationinfo -xml -wgs84 utm.vrt -117.5 33.75 + + + + utm.tif + + 16 + + + +.. example:: + :title: Reading locations from stdin + + .. code-block:: console + + $ cat coordinates.txt + 443020 3748359 + 441197 3749005 + 443852 3747743 + + $ cat coordinates.txt | gdallocationinfo -geoloc utmsmall.tif + Report: + Location: (38P,49L) + Band 1: + Value: 214 + Report: + Location: (7P,38L) + Band 1: + Value: 107 + Report: + Location: (52P,59L) + Band 1: + Value: 148 + + $ cat coordinates.txt | gdallocationinfo -geoloc -valonly -E -field_sep , utmsmall.tif + 443020,3748359,214 + 441197,3749005,107 + 443852,3747743,148 diff --git a/doc/source/programs/gdalmdiminfo.rst b/doc/source/programs/gdalmdiminfo.rst index e8287d8e3b86..3f91dff7026f 100644 --- a/doc/source/programs/gdalmdiminfo.rst +++ b/doc/source/programs/gdalmdiminfo.rst @@ -82,117 +82,119 @@ This utility is also callable from C with :cpp:func:`GDALMultiDimInfo`. Examples -------- -- Display general structure1 - -.. code-block:: - - $ gdalmdiminfo netcdf-4d.nc - - -.. code-block:: json - - { - "type": "group", - "name": "/", - "attributes": { - "Conventions": "CF-1.5" - }, - "dimensions": [ - { - "name": "levelist", - "full_name": "/levelist", - "size": 2, - "type": "VERTICAL", - "indexing_variable": "/levelist" - }, - { - "name": "longitude", - "full_name": "/longitude", - "size": 10, - "type": "HORIZONTAL_X", - "direction": "EAST", - "indexing_variable": "/longitude" - }, - { - "name": "latitude", - "full_name": "/latitude", - "size": 10, - "type": "HORIZONTAL_Y", - "direction": "NORTH", - "indexing_variable": "/latitude" - }, - { - "name": "time", - "full_name": "/time", - "size": 4, - "type": "TEMPORAL", - "indexing_variable": "/time" - } - ], - "arrays": { - "levelist": { - "datatype": "Int32", - "dimensions": [ - "/levelist" - ], - "attributes": { - "long_name": "pressure_level" - }, - "unit": "millibars" - }, - "longitude": { - "datatype": "Float32", - "dimensions": [ - "/longitude" - ], - "attributes": { - "standard_name": "longitude", - "long_name": "longitude", - "axis": "X" - }, - "unit": "degrees_east" - }, - "latitude": { - "datatype": "Float32", - "dimensions": [ - "/latitude" - ], - "attributes": { - "standard_name": "latitude", - "long_name": "latitude", - "axis": "Y" - }, - "unit": "degrees_north" - }, - "time": { - "datatype": "Float64", - "dimensions": [ - "/time" - ], - "attributes": { - "standard_name": "time", - "calendar": "standard" - }, - "unit": "hours since 1900-01-01 00:00:00" - }, - "t": { - "datatype": "Int32", - "dimensions": [ - "/time", - "/levelist", - "/latitude", - "/longitude" - ], - "nodata_value": -32767 - } - }, - "structural_info": { - "NC_FORMAT": "CLASSIC" - } - } - -- Display detailed information about a given array - -.. code-block:: - - $ gdalmdiminfo netcdf-4d.nc -array t -detailed -limit 3 +.. example:: + :title: Display general structure + + .. code-block:: console + + $ gdalmdiminfo netcdf-4d.nc + + + .. code-block:: json + + { + "type": "group", + "name": "/", + "attributes": { + "Conventions": "CF-1.5" + }, + "dimensions": [ + { + "name": "levelist", + "full_name": "/levelist", + "size": 2, + "type": "VERTICAL", + "indexing_variable": "/levelist" + }, + { + "name": "longitude", + "full_name": "/longitude", + "size": 10, + "type": "HORIZONTAL_X", + "direction": "EAST", + "indexing_variable": "/longitude" + }, + { + "name": "latitude", + "full_name": "/latitude", + "size": 10, + "type": "HORIZONTAL_Y", + "direction": "NORTH", + "indexing_variable": "/latitude" + }, + { + "name": "time", + "full_name": "/time", + "size": 4, + "type": "TEMPORAL", + "indexing_variable": "/time" + } + ], + "arrays": { + "levelist": { + "datatype": "Int32", + "dimensions": [ + "/levelist" + ], + "attributes": { + "long_name": "pressure_level" + }, + "unit": "millibars" + }, + "longitude": { + "datatype": "Float32", + "dimensions": [ + "/longitude" + ], + "attributes": { + "standard_name": "longitude", + "long_name": "longitude", + "axis": "X" + }, + "unit": "degrees_east" + }, + "latitude": { + "datatype": "Float32", + "dimensions": [ + "/latitude" + ], + "attributes": { + "standard_name": "latitude", + "long_name": "latitude", + "axis": "Y" + }, + "unit": "degrees_north" + }, + "time": { + "datatype": "Float64", + "dimensions": [ + "/time" + ], + "attributes": { + "standard_name": "time", + "calendar": "standard" + }, + "unit": "hours since 1900-01-01 00:00:00" + }, + "t": { + "datatype": "Int32", + "dimensions": [ + "/time", + "/levelist", + "/latitude", + "/longitude" + ], + "nodata_value": -32767 + } + }, + "structural_info": { + "NC_FORMAT": "CLASSIC" + } + } + +.. example:: + :title: Display detailed information about a given array + + .. code-block:: console + + $ gdalmdiminfo netcdf-4d.nc -array t -detailed -limit 3 diff --git a/doc/source/programs/gdalmdimtranslate.rst b/doc/source/programs/gdalmdimtranslate.rst index fdc37075ab08..c98c038af773 100644 --- a/doc/source/programs/gdalmdimtranslate.rst +++ b/doc/source/programs/gdalmdimtranslate.rst @@ -87,8 +87,10 @@ The following command line parameters can appear in any order. - [{axis1},{axis2},...] is the argument of :cpp:func:`GDALMDArray::Transpose`. For example, transpose=[1,0] switches the axis order of a 2D array. + See :example:`transpose`. - - {view_expr} is the value of the *viewExpr* argument of :cpp:func:`GDALMDArray::GetView` + - {view_expr} is the value of the *viewExpr* argument of :cpp:func:`GDALMDArray::GetView`. + See :example:`reorder`. When specifying a view_expr that performs a slicing or subsetting on a dimension, the equivalent operation will be applied to the corresponding indexing variable. @@ -128,7 +130,9 @@ The following command line parameters can appear in any order. to value sliced_val (and this dimension will be removed from the arrays that reference to it) - Using -subset is incompatible of specifying a *view* option in -array. + Using -subset is incompatible with specifying a *view* option in -array. + + See :example:`subset-1`. .. option:: -scaleaxes @@ -142,7 +146,9 @@ The following command line parameters can appear in any order. That is ()[,()]... - Using -scaleaxes is incompatible of specifying a *view* option in -array. + Using -scaleaxes is incompatible with specifying a *view* option in -array. + + See :example:`subsample-1`. .. option:: -strict @@ -172,33 +178,45 @@ This utility is also callable from C with :cpp:func:`GDALMultiDimTranslate`. Examples -------- -- Convert a netCDF file to a multidimensional VRT file +.. example:: + :title: Convert a netCDF file to a multidimensional VRT file -.. code-block:: + .. code-block:: bash - $ gdalmdimtranslate in.nc out.vrt + gdalmdimtranslate in.nc out.vrt -- Extract a 2D slice of a time,Y,X array +.. example:: + :title: Extract a 2D slice of a time,Y,X array + :id: subset-1 -.. code-block:: + .. code-block:: bash - $ gdalmdimtranslate in.nc out.tif -subset 'time("2010-01-01")' -array temperature + gdalmdimtranslate in.nc out.tif -subset 'time("2010-01-01")' -array temperature -- Subsample along X and Y axis +.. example:: + :title: Subsample along X and Y axis + :id: subsample-1 -.. code-block:: + .. code-block:: bash - $ gdalmdimtranslate in.nc out.nc -scaleaxes "X(2),Y(2)" + gdalmdimtranslate in.nc out.nc -scaleaxes "X(2),Y(2)" -- Reorder the values of a time,Y,X array along the Y axis from top-to-bottom - to bottom-to-top (or the reverse) +.. example:: + :title: Reorder the values of an array + :id: reorder -.. code-block:: + Reorder the values of the time,Y,X array along the Y axis from top-to-bottom + to bottom-to-top (or the reverse) - $ gdalmdimtranslate in.nc out.nc -array "name=temperature,view=[:,::-1,:]" + .. code-block:: bash -- Transpose an array that has X,Y,time dimension order to time,Y,X + gdalmdimtranslate in.nc out.nc -array "name=temperature,view=[:,::-1,:]" -.. code-block:: +.. example:: + :title: Transpose an array that has X,Y,time dimension order to time,Y,X + :id: transpose + + + .. code-block:: bash - $ gdalmdimtranslate in.nc out.nc -array "name=temperature,transpose=[2,1,0]" + gdalmdimtranslate in.nc out.nc -array "name=temperature,transpose=[2,1,0]" diff --git a/doc/source/programs/gdalsrsinfo.rst b/doc/source/programs/gdalsrsinfo.rst index 6b98be8fef73..80cd9d640c24 100644 --- a/doc/source/programs/gdalsrsinfo.rst +++ b/doc/source/programs/gdalsrsinfo.rst @@ -71,226 +71,28 @@ The :program:`gdalsrsinfo` utility reports information about a given SRS from on Example ------- -:: +.. example:: Default output - $ gdalsrsinfo EPSG:4326 + .. command-output:: gdalsrsinfo EPSG:4326 - PROJ.4 : +proj=longlat +datum=WGS84 +no_defs +.. example:: + :title: PROJ.4 output - OGC WKT : - GEOGCS["WGS 84", - DATUM["WGS_1984", - SPHEROID["WGS 84",6378137,298.257223563, - AUTHORITY["EPSG","7030"]], - AUTHORITY["EPSG","6326"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.0174532925199433, - AUTHORITY["EPSG","9122"]], - AUTHORITY["EPSG","4326"]] + .. command-output:: gdalsrsinfo -o proj4 lcc_esri.prj + :cwd: ../../../autotest/osr/data -:: - $ gdalsrsinfo -o proj4 osr/data/lcc_esri.prj - '+proj=lcc +lat_1=34.33333333333334 +lat_2=36.16666666666666 +lat_0=33.75 +lon_0=-79 +x_0=609601.22 +y_0=0 +datum=NAD83 +units=m +no_defs ' - -:: + .. code-block:: console $ gdalsrsinfo -o proj4 landsat.tif PROJ.4 : '+proj=utm +zone=19 +south +datum=WGS84 +units=m +no_defs ' -:: - - $ gdalsrsinfo -o wkt "EPSG:32722" - - PROJCRS["WGS 84 / UTM zone 22S", - BASEGEOGCRS["WGS 84", - DATUM["World Geodetic System 1984", - ELLIPSOID["WGS 84",6378137,298.257223563, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]]], - CONVERSION["UTM zone 22S", - METHOD["Transverse Mercator", - ID["EPSG",9807]], - PARAMETER["Latitude of natural origin",0, - ANGLEUNIT["degree",0.0174532925199433], - ID["EPSG",8801]], - PARAMETER["Longitude of natural origin",-51, - 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",10000000, - LENGTHUNIT["metre",1], - ID["EPSG",8807]]], - CS[Cartesian,2], - AXIS["(E)",east, - ORDER[1], - LENGTHUNIT["metre",1]], - AXIS["(N)",north, - ORDER[2], - LENGTHUNIT["metre",1]], - USAGE[ - SCOPE["unknown"], - AREA["World - S hemisphere - 54°W to 48°W - by country"], - BBOX[-80,-54,0,-48]], - ID["EPSG",32722]] - -:: - - $ gdalsrsinfo -o wkt_all "EPSG:4322" - OGC WKT 1: - GEOGCS["WGS 72", - DATUM["World_Geodetic_System_1972", - SPHEROID["WGS 72",6378135,298.26, - AUTHORITY["EPSG","7043"]], - TOWGS84[0,0,4.5,0,0,0.554,0.2263], - AUTHORITY["EPSG","6322"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.0174532925199433, - AUTHORITY["EPSG","9122"]], - AXIS["Latitude",NORTH], - AXIS["Longitude",EAST], - AUTHORITY["EPSG","4322"]] - - OGC WKT2:2015 : - BOUNDCRS[ - SOURCECRS[ - GEODCRS["WGS 72", - DATUM["World Geodetic System 1972", - ELLIPSOID["WGS 72",6378135,298.26, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]], - CS[ellipsoidal,2], - AXIS["geodetic latitude (Lat)",north, - ORDER[1], - ANGLEUNIT["degree",0.0174532925199433]], - AXIS["geodetic longitude (Lon)",east, - ORDER[2], - ANGLEUNIT["degree",0.0174532925199433]], - AREA["World"], - BBOX[-90,-180,90,180], - ID["EPSG",4322]]], - TARGETCRS[ - GEODCRS["WGS 84", - DATUM["World Geodetic System 1984", - ELLIPSOID["WGS 84",6378137,298.257223563, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]], - CS[ellipsoidal,2], - AXIS["latitude",north, - ORDER[1], - ANGLEUNIT["degree",0.0174532925199433]], - AXIS["longitude",east, - ORDER[2], - ANGLEUNIT["degree",0.0174532925199433]], - ID["EPSG",4326]]], - ABRIDGEDTRANSFORMATION["WGS 72 to WGS 84 (1)", - METHOD["Position Vector transformation (geog2D domain)", - ID["EPSG",9606]], - PARAMETER["X-axis translation",0, - ID["EPSG",8605]], - PARAMETER["Y-axis translation",0, - ID["EPSG",8606]], - PARAMETER["Z-axis translation",4.5, - ID["EPSG",8607]], - PARAMETER["X-axis rotation",0, - ID["EPSG",8608]], - PARAMETER["Y-axis rotation",0, - ID["EPSG",8609]], - PARAMETER["Z-axis rotation",0.554, - ID["EPSG",8610]], - PARAMETER["Scale difference",1.0000002263, - ID["EPSG",8611]], - AREA["World"], - BBOX[-90,-180,90,180], - ID["EPSG",1237]]] - - OGC WKT2:2019 : - BOUNDCRS[ - SOURCECRS[ - GEOGCRS["WGS 72", - DATUM["World Geodetic System 1972", - ELLIPSOID["WGS 72",6378135,298.26, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]], - CS[ellipsoidal,2], - AXIS["geodetic latitude (Lat)",north, - ORDER[1], - ANGLEUNIT["degree",0.0174532925199433]], - AXIS["geodetic longitude (Lon)",east, - ORDER[2], - ANGLEUNIT["degree",0.0174532925199433]], - USAGE[ - SCOPE["unknown"], - AREA["World"], - BBOX[-90,-180,90,180]], - ID["EPSG",4322]]], - TARGETCRS[ - GEOGCRS["WGS 84", - DATUM["World Geodetic System 1984", - ELLIPSOID["WGS 84",6378137,298.257223563, - LENGTHUNIT["metre",1]]], - PRIMEM["Greenwich",0, - ANGLEUNIT["degree",0.0174532925199433]], - CS[ellipsoidal,2], - AXIS["latitude",north, - ORDER[1], - ANGLEUNIT["degree",0.0174532925199433]], - AXIS["longitude",east, - ORDER[2], - ANGLEUNIT["degree",0.0174532925199433]], - ID["EPSG",4326]]], - ABRIDGEDTRANSFORMATION["WGS 72 to WGS 84 (1)", - METHOD["Position Vector transformation (geog2D domain)", - ID["EPSG",9606]], - PARAMETER["X-axis translation",0, - ID["EPSG",8605]], - PARAMETER["Y-axis translation",0, - ID["EPSG",8606]], - PARAMETER["Z-axis translation",4.5, - ID["EPSG",8607]], - PARAMETER["X-axis rotation",0, - ID["EPSG",8608]], - PARAMETER["Y-axis rotation",0, - ID["EPSG",8609]], - PARAMETER["Z-axis rotation",0.554, - ID["EPSG",8610]], - PARAMETER["Scale difference",1.0000002263, - ID["EPSG",8611]], - USAGE[ - SCOPE["unknown"], - AREA["World"], - BBOX[-90,-180,90,180]], - ID["EPSG",1237]]] - - OGC WKT 1 (simple) : - GEOGCS["WGS 72", - DATUM["World_Geodetic_System_1972", - SPHEROID["WGS 72",6378135,298.26], - TOWGS84[0,0,4.5,0,0,0.554,0.2263]], - PRIMEM["Greenwich",0], - UNIT["degree",0.0174532925199433]] - - OGC WKT 1 (no CT) : - GEOGCS["WGS 72", - DATUM["World_Geodetic_System_1972", - SPHEROID["WGS 72",6378135,298.26]], - PRIMEM["Greenwich",0], - UNIT["degree",0.0174532925199433]] - - ESRI WKT : - GEOGCS["GCS_WGS_1972", - DATUM["D_WGS_1972", - SPHEROID["WGS_1972",6378135.0,298.26]], - PRIMEM["Greenwich",0.0], - UNIT["Degree",0.0174532925199433]] +.. example:: + :title: WKT output, latest version + + .. command-output:: gdalsrsinfo -o wkt "EPSG:32722" + +.. example:: + :title: WKT output, all versions + + .. command-output:: gdalsrsinfo -o wkt_all "EPSG:4322" diff --git a/doc/source/programs/gdaltindex.rst b/doc/source/programs/gdaltindex.rst index a9e8a0b8cb87..b9908ef57c0a 100644 --- a/doc/source/programs/gdaltindex.rst +++ b/doc/source/programs/gdaltindex.rst @@ -303,34 +303,42 @@ specified. Examples -------- -- Produce a shapefile (``doq_index.shp``) with a record for every - image that the utility found in the ``doq`` folder. Each record holds - information that points to the location of the image and also a bounding rectangle - shape showing the bounds of the image: +.. example:: -:: + Produce a shapefile (``doq_index.shp``) with a record for every + image that the utility found in the ``doq`` folder. Each record holds + information that points to the location of the image and also a bounding rectangle + shape showing the bounds of the image: - gdaltindex doq_index.shp doq/*.tif + .. code-block:: bash -- Perform the same command as before, but now we create a GeoPackage instead of a Shapefile. + gdaltindex doq_index.shp doq/*.tif -:: +.. example:: - gdaltindex -f GPKG doq_index.gpkg doq/*.tif + Perform the same command as before, but now we create a GeoPackage instead of a Shapefile. -- The :option:`-t_srs` option can also be used to transform all input rasters - into the same output projection: + .. code-block:: bash -:: + gdaltindex -f GPKG doq_index.gpkg doq/*.tif - gdaltindex -t_srs EPSG:4326 -src_srs_name src_srs tile_index_mixed_srs.shp *.tif +.. example:: -- Make a tile index from files listed in a text file, with metadata suitable - for use by the GDAL GTI / Virtual Raster Tile Index driver. + The :option:`-t_srs` option can also be used to transform all input rasters + into the same output projection: -:: + .. code-block:: bash - gdaltindex tile_index.gti.gpkg -ot Byte -tr 60 60 -colorinterp Red,Green,Blue --optfile my_list.txt + gdaltindex -t_srs EPSG:4326 -src_srs_name src_srs tile_index_mixed_srs.shp *.tif + +.. example:: + + Make a tile index from files listed in a text file, with metadata suitable + for use by the GDAL GTI / Virtual Raster Tile Index driver. + + .. code-block:: bash + + gdaltindex tile_index.gti.gpkg -ot Byte -tr 60 60 -colorinterp Red,Green,Blue --optfile my_list.txt C API ----- diff --git a/doc/source/programs/gdalwarp.rst b/doc/source/programs/gdalwarp.rst index 2f559bdcb716..e3d49f3e0557 100644 --- a/doc/source/programs/gdalwarp.rst +++ b/doc/source/programs/gdalwarp.rst @@ -214,10 +214,10 @@ with control information. .. option:: -et - Error threshold for transformation approximation in source pixel units. - Defaults to 0.125 source pixels unless the ``RPC_DEM`` transformer - option is specified, in which case, an exact transformer, i.e. - ``err_threshold=0``, will be used). + Error threshold for transformation approximation, expressed as a number of + source pixels. Defaults to 0.125 pixels unless the ``RPC_DEM`` transformer + option is specified, in which case an exact transformer, i.e. + ``err_threshold=0``, will be used. .. option:: -refine_gcps [] @@ -385,8 +385,13 @@ with control information. .. option:: -wm Set the amount of memory that the - warp API is allowed to use for caching. The value is interpreted as being - in megabytes if the value is less than 10000. For values >=10000, this is + warp API is allowed to use for caching. + Defaults to 64 MB. + Since GDAL 3.10, the value can be specified either as a fixed amount of + memory (e.g., ``-wm 200MB``, ``-wm 1G``) or as a percentage of usable + RAM (``-wm 10%``). + In earlier versions, or if a unit is not specified, the value is interpreted as being + in megabytes if the value is less than 10000. For values >=10000, it is interpreted as bytes. The warper will total up the memory required to hold the input and output @@ -490,21 +495,60 @@ with control information. The destination file name. -Mosaicing into an existing output file is supported if the output file -already exists. The spatial extent of the existing file will not -be modified to accommodate new data, so you may have to remove it in that case, or -use the -overwrite option. +Overview +-------- -Polygon cutlines may be used as a mask to restrict the area of the -destination file that may be updated, including blending. If the OGR -layer containing the cutline features has no explicit SRS, the cutline -features must be in the SRS of the destination file. When writing to a -not yet existing target dataset, its extent will be the one of the -original raster unless -te or -crop_to_cutline are specified. +:program:`gdalwarp` transforms images between different coordinate reference +systems and spatial resolutions. + +First, :program:`gdalwarp` must determine the extent and resolution of the +output, if these have not been specified using :option:`-te` and :option:`-tr`. +These are determined by transforming a sample of points from the source CRS to +the destination CRS. Details of the procedure can be found in the documentation +for :cpp:func:`GDALSuggestedWarpOutput`. If multiple inputs are provided to +:program:`gdalwarp`, the output extent will be calculated to cover all of them, +at a resolution consistent with the highest-resolution input. + +Once the dimensions of the output image have been determined, +:program:`gdalwarp` divides the output image into chunks that can be processed +independently within the amount of memory specified by :option:`-wm`. +:program:`gdalwarp` then iterates over scanlines in these chunks, and for each +output pixel determines a rectangular region of source pixels that contribute +to the value of the output pixel. The dimensions of this rectangular region +are typically determined by estimating the relative scales of the source and +destination raster, but can be manually specified (see documentation of the +``XSCALE`` parameter in :cpp:member:`GDALWarpOptions::papszWarpOptions`). +Because the source region is a simple rectangle, it is not possible for an +output pixel to be associated with source pixels from both sides of the +antimeridian or pole (when transforming from geographic coordinates). + +The rectangular region of source pixels is then provided to a function that +performs the resampling algorithm selected with :option:`-r`. Depending on the +resampling algorithm and relative scales of the source and destination rasters, +source pixels may be weighted either according to the approximate fraction of +the source pixel that is covered by the destination pixel (e.g., "mean" and +"sum" resampling), or by horizontal and vertical Cartesian distances between +the center of the source pixel and the center of the target pixel (e.g., +bilinear or cubic spline resampling). In the latter case, the relative weight +of an individual source pixel is determined by the product of the weights +determined for its row and column; the diagonal Cartesian distance is not +calculated. + +Writing to an existing file +--------------------------- + +Mosaicing into an existing output file is supported if the output file already +exists. The spatial extent of the existing file will not be modified to +accommodate new data, so you may have to remove it in that case, or use the +:option:`-overwrite` option. + +Polygon cutlines may be used as a mask to restrict the area of the destination +file that may be updated, including blending. If the OGR layer containing the +cutline features has no explicit SRS, the cutline features are assumed to be in +the SRS of the destination file. When writing to a not yet existing target +dataset, its extent will be the one of the original raster unless :option:`-te` +or :option:`-crop_to_cutline` are specified. -Starting with GDAL 3.1, it is possible to use as output format a driver that -only supports the CreateCopy operation. This may internally imply creation of -a temporary file. .. _gdalwarp_nodata: @@ -580,13 +624,13 @@ use :option:`-et 0` which disables this approximator entirely. Vertical transformation ----------------------- -While gdalwarp can essentially perform coordinate transformations in the 2D -space, it can perform as well vertical transformations. This is automatically -enabled when the 2 following conditions are met: +While gdalwarp is most commonly used to perform coordinate transformations in the 2D +space, it can also perform vertical transformations. Vertical transformations are +automatically performed when the following two conditions are met: - at least one of the source or target CRS has an explicit vertical CRS - (as part of a compound CRS) or is a 3D (generally geographic) CRS, -- and the raster has a single band. + (as part of a compound CRS) or is a 3D (generally geographic) CRS, and +- the raster has a single band This mode can also be forced by using the :option:`-vshift` (this is essentially useful when the CRS involved are not explicitly 3D, but a diff --git a/doc/source/programs/index.rst b/doc/source/programs/index.rst index af107ef12aa5..a6ab1e221b56 100644 --- a/doc/source/programs/index.rst +++ b/doc/source/programs/index.rst @@ -50,6 +50,7 @@ Raster programs gdalbuildvrt gdalcompare gdaldem + gdalenhance gdalinfo gdallocationinfo gdalmanage @@ -89,6 +90,7 @@ Raster programs - :ref:`gdalbuildvrt`: Builds a VRT from a list of datasets. - :ref:`gdalcompare`: Compare two images. - :ref:`gdaldem`: Tools to analyze and visualize DEMs. + - :ref:`gdalenhance`: Enhance an image with LUT-based contrast enhancement - :ref:`gdalinfo`: Lists information about a raster dataset. - :ref:`gdallocationinfo`: Raster query tool - :ref:`gdalmanage`: Identify, delete, rename and copy raster data files. diff --git a/doc/source/programs/ogr2ogr.rst b/doc/source/programs/ogr2ogr.rst index abf20038d4de..56a953be7c25 100644 --- a/doc/source/programs/ogr2ogr.rst +++ b/doc/source/programs/ogr2ogr.rst @@ -153,7 +153,7 @@ output coordinate system or even reprojecting the features during translation. Display progress on terminal. Only works if input layers have the "fast feature count" capability. -.. option:: -sql +.. option:: -sql |@ SQL statement to execute. The resulting table/layer will be saved to the output. Starting with GDAL 2.1, the ``@filename`` syntax can be used to @@ -166,7 +166,7 @@ output coordinate system or even reprojecting the features during translation. The :ref:`sql_sqlite_dialect` dialect can be chosen with the ``SQLITE`` and ``INDIRECT_SQLITE`` dialect values, and this can be used with any datasource. -.. option:: -where +.. option:: -where |@ Attribute query (like SQL WHERE). Starting with GDAL 2.1, the ``@filename`` syntax can be used to indicate that the content is in the pointed filename. @@ -697,31 +697,38 @@ This utility is also callable from C with :cpp:func:`GDALVectorTranslate`. Examples -------- -* Basic conversion from Shapefile to GeoPackage: +.. example: + :title: Basic conversion from Shapefile to GeoPackage .. code-block:: bash ogr2ogr output.gpkg input.shp -* Change the coordinate reference system from ``EPSG:4326`` to ``EPSG:3857``: +.. example: + :title: Change the coordinate reference system from ``EPSG:4326`` to ``EPSG:3857`` .. code-block:: bash ogr2ogr -s_srs EPSG:4326 -t_srs EPSG:3857 output.gpkg input.gpkg -* Example appending to an existing layer: +.. example:: + :title: Appending to an existing layer .. code-block:: bash ogr2ogr -append -f PostgreSQL PG:dbname=warmerda abc.tab -* Clip input layer with a bounding box ( ): +.. example:: + :title: Clip input layer with a bounding box + + The bounding box is specified as `` ``: .. code-block:: bash ogr2ogr -spat -13.931 34.886 46.23 74.12 output.gpkg natural_earth_vector.gpkg -* Filter Features by a ``-where`` clause: +.. example:: + :title: Filter Features by a ``-where`` clause .. code-block:: bash @@ -734,62 +741,68 @@ More examples are given in the individual format pages. Advanced examples ----------------- -* Reprojecting from ETRS_1989_LAEA_52N_10E to EPSG:4326 and clipping to a bounding box: +.. example:: + :title: Reprojecting from ETRS_1989_LAEA_52N_10E to EPSG:4326 and clipping to a bounding box .. code-block:: bash ogr2ogr -wrapdateline -t_srs EPSG:4326 -clipdst -5 40 15 55 france_4326.shp europe_laea.shp -* Using the ``-fieldmap`` setting. The first field of the source layer is - used to fill the third field (index 2 = third field) of the target layer, the - second field of the source layer is ignored, the third field of the source - layer used to fill the fifth field of the target layer. +.. example: + :title: Using the ``-fieldmap`` setting + + The first field of the source layer is + used to fill the third field (index 2 = third field) of the target layer, the + second field of the source layer is ignored, the third field of the source + layer used to fill the fifth field of the target layer. .. code-block:: bash ogr2ogr -append -fieldmap 2,-1,4 dst.shp src.shp -* Outputting geometries with the CSV driver. +.. example:: + :title: Outputting geometries with the CSV driver. - By default, this driver does not preserve geometries on layer creation by - default. An explicit layer creation option is needed: + By default, this driver does not preserve geometries on layer creation by + default. An explicit layer creation option is needed: .. code-block:: bash ogr2ogr -lco GEOMETRY=AS_XYZ TrackWaypoint.csv TrackWaypoint.kml -* Extracting only geometries. +.. example:: + :title: Extracting only geometries - There are different situations, depending if the input layer has a named geometry - column, or not. First check, with ogrinfo if there is a reported geometry column. + There are different situations, depending if the input layer has a named geometry + column, or not. First check, with :program:`ogrinfo` if there is a reported geometry column. - .. code-block:: bash + .. code-block:: console - ogrinfo -so CadNSDI.gdb.zip PLSSPoint | grep 'Geometry Column' + $ ogrinfo -so CadNSDI.gdb.zip PLSSPoint | grep 'Geometry Column' Geometry Column = SHAPE - In that situation where the input format is a FileGeodatabase, it is called SHAPE - and can thus be referenced directly in a SELECT statement. + In that situation where the input format is a FileGeodatabase, it is called SHAPE + and can thus be referenced directly in a SELECT statement. .. code-block:: bash ogr2ogr -sql "SELECT SHAPE FROM PLSSPoint" \ -lco GEOMETRY=AS_XY -f CSV /vsistdout/ CadNSDI.gdb.zip - For a shapefile with a unnamed geometry column, ``_ogr_geometry_`` can be used as - a special name to designate the implicit geometry column, when using the default - :ref:`OGR SQL ` dialect. The name begins with - an underscore and SQL syntax requires that it must appear between double quotes. - In addition the command line interpreter may require that double quotes are - escaped and the final SELECT statement could look like: + For a shapefile with a unnamed geometry column, ``_ogr_geometry_`` can be used as + a special name to designate the implicit geometry column, when using the default + :ref:`OGR SQL ` dialect. The name begins with + an underscore and SQL syntax requires that it must appear between double quotes. + In addition the command line interpreter may require that double quotes are + escaped and the final SELECT statement could look like: .. code-block:: bash ogr2ogr -sql "SELECT \"_ogr_geometry_\" FROM PLSSPoint" \ -lco GEOMETRY=AS_XY -f CSV /vsistdout/ CadNSDI.shp - If using the :ref:`SQL SQLite ` dialect, the special geometry - name is ``geometry`` when the source geometry column has no name. + If using the :ref:`SQL SQLite ` dialect, the special geometry + name is ``geometry`` when the source geometry column has no name. .. code-block:: bash diff --git a/doc/source/programs/ogrinfo.rst b/doc/source/programs/ogrinfo.rst index 3bcd4773924d..3c526dcd5bd3 100644 --- a/doc/source/programs/ogrinfo.rst +++ b/doc/source/programs/ogrinfo.rst @@ -17,7 +17,7 @@ Synopsis .. code-block:: ogrinfo [--help] [--help-general] - [-if ] [-json] [-ro] [-q] [-where |@f] + [-if ] [-json] [-ro] [-q] [-where |@] [-spat ] [-geomfield ] [-fid ] [-sql |@] [-dialect ] [-al] [-rl] [-so|-features] [-limit ] [-fields={YES|NO}]] @@ -251,27 +251,29 @@ This utility is also callable from C with :cpp:func:`GDALVectorInfo`. Examples -------- -Example of reporting the names of the layers in a NTF file: +.. example:: + :title: Reporting the names of the layers in a NTF file -.. code-block:: + .. code-block:: console - ogrinfo wrk/SHETLAND_ISLANDS.NTF + $ ogrinfo wrk/SHETLAND_ISLANDS.NTF - INFO: Open of `wrk/SHETLAND_ISLANDS.NTF' - using driver `UK .NTF' successful. - 1: BL2000_LINK (Line String) - 2: BL2000_POLY (None) - 3: BL2000_COLLECTIONS (None) - 4: FEATURE_CLASSES (None) + INFO: Open of `wrk/SHETLAND_ISLANDS.NTF' + using driver `UK .NTF' successful. + 1: BL2000_LINK (Line String) + 2: BL2000_POLY (None) + 3: BL2000_COLLECTIONS (None) + 4: FEATURE_CLASSES (None) -Example of retrieving a summary (``-so``) of a layer without showing details about every single feature: +.. example:: + :title: Retrieving a summary (``-so``) of a layer without showing details about every feature -.. code-block:: + .. code-block:: console - ogrinfo \ - -so \ - natural_earth_vector.gpkg \ - ne_10m_admin_0_antarctic_claim_limit_lines + $ ogrinfo \ + -so \ + natural_earth_vector.gpkg \ + ne_10m_admin_0_antarctic_claim_limit_lines INFO: Open of `natural_earth_vector.gpkg' using driver `GPKG' successful. @@ -297,244 +299,250 @@ Example of retrieving a summary (``-so``) of a layer without showing details abo scalerank: Integer (0.0) featurecla: String (50.0) -Example of retrieving information on a file in JSON format without showing details about every single feature: - -.. code-block:: - - ogrinfo -json poly.shp - - -.. code-block:: json - - { - "description":"autotest/ogr/data/poly.shp", - "driverShortName":"ESRI Shapefile", - "driverLongName":"ESRI Shapefile", - "layers":[ - { - "name":"poly", - "metadata":{ - "":{ - "DBF_DATE_LAST_UPDATE":"2018-08-02" - }, - "SHAPEFILE":{ - "SOURCE_ENCODING":"" - } - }, - "geometryFields":[ - { - "name":"", - "type":"Polygon", - "nullable":true, - "extent":[ - 478315.53125, - 4762880.5, - 481645.3125, - 4765610.5 - ], - "coordinateSystem":{ - "wkt":"PROJCRS[\"OSGB36 / British National Grid\",BASEGEOGCRS[\"OSGB36\",DATUM...", - "projjson":{ - "$schema":"https://proj.org/schemas/v0.6/projjson.schema.json", - "type":"ProjectedCRS", - "name":"OSGB36 / British National Grid", - "base_crs":{ - "name":"OSGB36", - "datum":{ - "type":"GeodeticReferenceFrame", - "name":"Ordnance Survey of Great Britain 1936", - "ellipsoid":{ - "name":"Airy 1830", - "semi_major_axis":6377563.396, - "inverse_flattening":299.3249646 - } - }, - "coordinate_system":{ - "subtype":"ellipsoidal", - "axis":[ - { - "name":"Geodetic latitude", - "abbreviation":"Lat", - "direction":"north", - "unit":"degree" - }, - { - "name":"Geodetic longitude", - "abbreviation":"Lon", - "direction":"east", - "unit":"degree" - } - ] - }, - "id":{ - "authority":"EPSG", - "code":4277 - } - }, - "conversion":{ - "name":"British National Grid", - "method":{ - "name":"Transverse Mercator", - "id":{ - "authority":"EPSG", - "code":9807 - } - }, - "parameters":[ - { - "name":"Latitude of natural origin", - "value":49, - "unit":"degree", - "id":{ - "authority":"EPSG", - "code":8801 - } - }, - { - "name":"Longitude of natural origin", - "value":-2, - "unit":"degree", - "id":{ - "authority":"EPSG", - "code":8802 - } - }, - { - "name":"Scale factor at natural origin", - "value":0.9996012717, - "unit":"unity", - "id":{ - "authority":"EPSG", - "code":8805 - } - }, - { - "name":"False easting", - "value":400000, - "unit":"metre", - "id":{ - "authority":"EPSG", - "code":8806 - } - }, - { - "name":"False northing", - "value":-100000, - "unit":"metre", - "id":{ - "authority":"EPSG", - "code":8807 - } - } - ] - }, - "coordinate_system":{ - "subtype":"Cartesian", - "axis":[ - { - "name":"Easting", - "abbreviation":"E", - "direction":"east", - "unit":"metre" - }, - { - "name":"Northing", - "abbreviation":"N", - "direction":"north", - "unit":"metre" - } - ] - }, - "scope":"Engineering survey, topographic mapping.", - "area":"United Kingdom (UK) - offshore to boundary of UKCS within 49°45...", - "bbox":{ - "south_latitude":49.75, - "west_longitude":-9, - "north_latitude":61.01, - "east_longitude":2.01 - }, - "id":{ - "authority":"EPSG", - "code":27700 - } - }, - "dataAxisToSRSAxisMapping":[ - 1, - 2 - ] - } - } - ], - "featureCount":10, - "fields":[ - { - "name":"AREA", - "type":"Real", - "width":12, - "precision":3, - "nullable":true, - "uniqueConstraint":false - }, - { - "name":"EAS_ID", - "type":"Integer64", - "width":11, - "nullable":true, - "uniqueConstraint":false - }, - { - "name":"PRFEDEA", - "type":"String", - "width":16, - "nullable":true, - "uniqueConstraint":false - } - ] - } - ], - "metadata":{ - }, - "domains":{ - }, - "relationships":{ - } - } - - -Example of using -q and an attribute query, to restrict the output to -certain features in a layer: - -.. code-block:: bash - - ogrinfo -q -ro \ - -where 'GLOBAL_LINK_ID=185878' \ - wrk/SHETLAND_ISLANDS.NTF BL2000_LINK - - Layer name: BL2000_LINK - OGRFeature(BL2000_LINK):2 - LINE_ID (Integer) = 2 - GEOM_ID (Integer) = 2 - FEAT_CODE (String) = (null) - GLOBAL_LINK_ID (Integer) = 185878 - TILE_REF (String) = SHETLAND I - LINESTRING (419832.100 1069046.300,419820.100 1069043.800,... - -Example of updating a value of an attribute in a shapefile with SQL by using the SQLite dialect: - -.. code-block:: bash - - ogrinfo test.shp -dialect sqlite -sql "update test set attr='bar' where attr='foo'" - -Adding a column to an input file: - -.. code-block:: bash - - ogrinfo input.shp -sql "ALTER TABLE input ADD fieldX float" - -Sometimes there is no input file involved in a calculation. In such cases one may -use the ``:memory:`` input file which is a in-memory empty SQLite file (and the SQLite SQL dialect will be implicitly used). - -.. code-block:: bash - - ogrinfo :memory: -sql "SELECT ST_Buffer(ST_GeomFromText('POINT(0 0)'), 1)" +.. example:: + :title: Retrieving information on a file in JSON format without showing details about every feature + + .. code-block:: + + ogrinfo -json poly.shp + + + .. code-block:: json + + { + "description":"autotest/ogr/data/poly.shp", + "driverShortName":"ESRI Shapefile", + "driverLongName":"ESRI Shapefile", + "layers":[ + { + "name":"poly", + "metadata":{ + "":{ + "DBF_DATE_LAST_UPDATE":"2018-08-02" + }, + "SHAPEFILE":{ + "SOURCE_ENCODING":"" + } + }, + "geometryFields":[ + { + "name":"", + "type":"Polygon", + "nullable":true, + "extent":[ + 478315.53125, + 4762880.5, + 481645.3125, + 4765610.5 + ], + "coordinateSystem":{ + "wkt":"PROJCRS[\"OSGB36 / British National Grid\",BASEGEOGCRS[\"OSGB36\",DATUM...", + "projjson":{ + "$schema":"https://proj.org/schemas/v0.6/projjson.schema.json", + "type":"ProjectedCRS", + "name":"OSGB36 / British National Grid", + "base_crs":{ + "name":"OSGB36", + "datum":{ + "type":"GeodeticReferenceFrame", + "name":"Ordnance Survey of Great Britain 1936", + "ellipsoid":{ + "name":"Airy 1830", + "semi_major_axis":6377563.396, + "inverse_flattening":299.3249646 + } + }, + "coordinate_system":{ + "subtype":"ellipsoidal", + "axis":[ + { + "name":"Geodetic latitude", + "abbreviation":"Lat", + "direction":"north", + "unit":"degree" + }, + { + "name":"Geodetic longitude", + "abbreviation":"Lon", + "direction":"east", + "unit":"degree" + } + ] + }, + "id":{ + "authority":"EPSG", + "code":4277 + } + }, + "conversion":{ + "name":"British National Grid", + "method":{ + "name":"Transverse Mercator", + "id":{ + "authority":"EPSG", + "code":9807 + } + }, + "parameters":[ + { + "name":"Latitude of natural origin", + "value":49, + "unit":"degree", + "id":{ + "authority":"EPSG", + "code":8801 + } + }, + { + "name":"Longitude of natural origin", + "value":-2, + "unit":"degree", + "id":{ + "authority":"EPSG", + "code":8802 + } + }, + { + "name":"Scale factor at natural origin", + "value":0.9996012717, + "unit":"unity", + "id":{ + "authority":"EPSG", + "code":8805 + } + }, + { + "name":"False easting", + "value":400000, + "unit":"metre", + "id":{ + "authority":"EPSG", + "code":8806 + } + }, + { + "name":"False northing", + "value":-100000, + "unit":"metre", + "id":{ + "authority":"EPSG", + "code":8807 + } + } + ] + }, + "coordinate_system":{ + "subtype":"Cartesian", + "axis":[ + { + "name":"Easting", + "abbreviation":"E", + "direction":"east", + "unit":"metre" + }, + { + "name":"Northing", + "abbreviation":"N", + "direction":"north", + "unit":"metre" + } + ] + }, + "scope":"Engineering survey, topographic mapping.", + "area":"United Kingdom (UK) - offshore to boundary of UKCS within 49°45...", + "bbox":{ + "south_latitude":49.75, + "west_longitude":-9, + "north_latitude":61.01, + "east_longitude":2.01 + }, + "id":{ + "authority":"EPSG", + "code":27700 + } + }, + "dataAxisToSRSAxisMapping":[ + 1, + 2 + ] + } + } + ], + "featureCount":10, + "fields":[ + { + "name":"AREA", + "type":"Real", + "width":12, + "precision":3, + "nullable":true, + "uniqueConstraint":false + }, + { + "name":"EAS_ID", + "type":"Integer64", + "width":11, + "nullable":true, + "uniqueConstraint":false + }, + { + "name":"PRFEDEA", + "type":"String", + "width":16, + "nullable":true, + "uniqueConstraint":false + } + ] + } + ], + "metadata":{ + }, + "domains":{ + }, + "relationships":{ + } + } + + +.. example:: + :title: Using :option:`-q` and an attribute query to restrict the output to certain features in a layer + + .. code-block:: console + + $ ogrinfo -q -ro \ + -where 'GLOBAL_LINK_ID=185878' \ + wrk/SHETLAND_ISLANDS.NTF BL2000_LINK + + Layer name: BL2000_LINK + OGRFeature(BL2000_LINK):2 + LINE_ID (Integer) = 2 + GEOM_ID (Integer) = 2 + FEAT_CODE (String) = (null) + GLOBAL_LINK_ID (Integer) = 185878 + TILE_REF (String) = SHETLAND I + LINESTRING (419832.100 1069046.300,419820.100 1069043.800,... + +.. example:: + :title: Updating a value of an attribute in a shapefile with SQL by using the SQLite dialect + + .. code-block:: bash + + ogrinfo test.shp -dialect sqlite -sql "update test set attr='bar' where attr='foo'" + +.. example:: + :title: Adding a column to an input file + + .. code-block:: bash + + ogrinfo input.shp -sql "ALTER TABLE input ADD fieldX float" + +.. example:: + :title: Performing a SQL query without an input file + + Sometimes there is no input file involved in a calculation. In such cases one may + use the ``:memory:`` input file which is a in-memory empty SQLite file (and the SQLite SQL dialect will be implicitly used). + + .. code-block:: bash + + ogrinfo :memory: -sql "SELECT ST_Buffer(ST_GeomFromText('POINT(0 0)'), 1)" diff --git a/doc/source/programs/ogrlineref.rst b/doc/source/programs/ogrlineref.rst index b3969b1d1875..7f280bed2f84 100644 --- a/doc/source/programs/ogrlineref.rst +++ b/doc/source/programs/ogrlineref.rst @@ -160,12 +160,14 @@ Also some information is written to the stdout. The input end linear distance -Example -------- +Examples +-------- -This example would create a shapefile (:file:`parts.shp`) containing -a data needed for linear referencing (1 km parts): +.. example:: -.. code-block:: + This example would create a shapefile (:file:`parts.shp`) containing + a data needed for linear referencing (1 km parts): + + .. code-block:: bash - ogrlineref -create -l roads.shp -p references.shp -pm dist -o parts.shp -s 1000 -progress + ogrlineref -create -l roads.shp -p references.shp -pm dist -o parts.shp -s 1000 -progress diff --git a/doc/source/programs/ogrmerge.rst b/doc/source/programs/ogrmerge.rst index 743e1f5d378d..6ec2323c4b8b 100644 --- a/doc/source/programs/ogrmerge.rst +++ b/doc/source/programs/ogrmerge.rst @@ -170,7 +170,7 @@ potential manual editing of it and :program:`ogr2ogr` can be done. Only used with :option:`-single`. If specified, the schema of the target layer will be extended with a new field 'name', whose content is - determined by -src_layer_field_content. + determined by -src_layer_field_content. See :example:`src-layer-field-name`. .. option:: -src_layer_field_content @@ -183,22 +183,29 @@ potential manual editing of it and :program:`ogr2ogr` can be done. Examples -------- -Create a VRT with a layer for each input shapefiles +.. example:: + :title: Creating a VRT with a layer for each input shapefile -.. code-block:: + .. code-block:: bash - ogrmerge -f VRT -o merged.vrt *.shp + ogrmerge -f VRT -o merged.vrt *.shp -Same, but creates a GeoPackage file -.. code-block:: +.. example:: + :title: Creating a GeoPackage with a layer for each input shapefile - ogrmerge -f GPKG -o merged.gpkg *.shp + .. code-block:: bash -Concatenate the content of france.shp and germany.shp in merged.shp, -and adds a 'country' field to each feature whose value is 'france' or -'germany' depending where it comes from. + ogrmerge -f GPKG -o merged.gpkg *.shp -.. code-block:: +.. example:: + :title: Adding a field to indicate the source layer + :id: src-layer-field-name + + Concatenate the content of :file:`france.shp` and :file:`germany.shp` in :file:`merged.shp`, + and add a 'country' field to each feature whose value is 'france' or + 'germany' depending where it comes from: + + .. code-block:: bash - ogrmerge -single -o merged.shp france.shp germany.shp -src_layer_field_name country + ogrmerge -single -o merged.shp france.shp germany.shp -src_layer_field_name country diff --git a/doc/source/programs/ogrtindex.rst b/doc/source/programs/ogrtindex.rst index dc18e9eba599..98c7e5199870 100644 --- a/doc/source/programs/ogrtindex.rst +++ b/doc/source/programs/ogrtindex.rst @@ -100,13 +100,15 @@ independent records. If the tile index already exists it will be appended to, otherwise it will be created. -Example -------- +Examples +-------- -This example would create a shapefile (:file:`tindex.shp`) containing -a tile index of the ``BL2000_LINK`` layers in all the NTF files -in the :file:`wrk` directory: +.. example:: -.. code-block:: + This example would create a shapefile (:file:`tindex.shp`) containing + a tile index of the ``BL2000_LINK`` layers in all the NTF files + in the :file:`wrk` directory: + + .. code-block:: bash - ogrtindex tindex.shp wrk/*.NTF + ogrtindex tindex.shp wrk/*.NTF diff --git a/doc/source/programs/raster_common_options.rst b/doc/source/programs/raster_common_options.rst index e976b9a254d6..de42edb5ccf6 100644 --- a/doc/source/programs/raster_common_options.rst +++ b/doc/source/programs/raster_common_options.rst @@ -21,6 +21,10 @@ All GDAL command line programs support the following common options. List detailed information about a single format driver. The format should be the short name reported in the --formats list, such as GTiff. +.. option:: --formats + + List all drivers. Can be combined with ``-json`` switch of :program:`gdalinfo` of since GDAL 3.10 + .. _raster_common_options_optfile: .. option:: --optfile diff --git a/doc/source/programs/rgb2pct.rst b/doc/source/programs/rgb2pct.rst index c6479dc3017f..5b8c01a5bd55 100644 --- a/doc/source/programs/rgb2pct.rst +++ b/doc/source/programs/rgb2pct.rst @@ -70,10 +70,10 @@ is the GDAL VRT format. In the following example a VRT was created in a text editor with a small 4 color palette with the RGBA colors 238/238/238/255, 237/237/237/255, 236/236/236/255 and 229/229/229/255. -:: +.. code-block:: console - rgb2pct -pct palette.vrt rgb.tif pseudo-colored.tif - more < palette.vrt + $ rgb2pct -pct palette.vrt rgb.tif pseudo-colored.tif + $ more < palette.vrt Palette diff --git a/doc/source/programs/vector_common_options.rst b/doc/source/programs/vector_common_options.rst index 8e281e088bbc..152f75c3c5dc 100644 --- a/doc/source/programs/vector_common_options.rst +++ b/doc/source/programs/vector_common_options.rst @@ -22,6 +22,10 @@ All GDAL OGR command line programs support the following common options. The format should be the short name reported in the :option:`--formats` list, such as GML. +.. option:: --formats + + List all drivers. Can be combined with ``-json`` switch of :program:`ogrinfo` of since GDAL 3.10 + .. option:: --optfile Read the named file and substitute the contents into the command line diff --git a/doc/source/software_using_gdal.rst b/doc/source/software_using_gdal.rst index 55d89e21c47f..217f107f5647 100644 --- a/doc/source/software_using_gdal.rst +++ b/doc/source/software_using_gdal.rst @@ -21,12 +21,13 @@ Free and open source - `GdalToTiles `_ C# Program (open source) for making image tiles for Google Earth with KML Superoverlay. - `GeoDa `_ Introduction to Spatial Data Analysis (spatial autocorrelation and spatial regression) (GPL) - `GeoDjango `_ A framework for building geographic web applications. -- `GeoKettle `_ An open source spatial ETL (Extract, Transform and Load) tool (LGPL) +- `geofileops `_ Python toolbox to process large vector files faster. +- `GeoKettle `_ An open source spatial ETL (Extract, Transform and Load) tool (LGPL) - `GeoNotebook `_ a Jupyter notebook extension for geospatial visualization and analysis. (Apache 2.0) -- `GeoServer `_ a open source software server written in Java that allows users to share and edit geospatial data. +- `GeoServer `_ a open source software server written in Java that allows users to share and edit geospatial data. - `GMT (Generic Mapping Tools) `_ an open source collection of tools for processing and displaying xy and xyz datasets. -- `GRASS GIS `_ A raster/vector open source GIS that uses GDAL for raster/vector import and export (via r.in.gdal/r.out.gdal) -- `gstat `_ a geostatistical modelling package. +- `GRASS GIS `_ A raster/vector open source GIS that uses GDAL for raster/vector import and export (via r.in.gdal/r.out.gdal) +- `gstat `_ a geostatistical modelling package. - `GuidosToolbox `_ A multi-platform desktop application for generic image object analysis. - `gvSIG `_ Desktop GIS Client. - `ILWIS `_ Remote Sensing and GIS Desktop Package. @@ -35,7 +36,7 @@ Free and open source - `Loader `_ A simple loader for geographic data in GML and KML that needs some preparation before loading via ogr2ogr. - `MapGuide `_ Open source web mapping server. - `Mapnik `_ C++/ Python mapping toolkit -- `MapServer `_ A popular web mapping application with GDAL support. +- `MapServer `_ A popular web mapping application with GDAL support. - `MapWindow `_ open source ActiveX control with GIS functionality. - `MultiSpec `_ Application for interactively analyzing multispectral/hyperspectral image data. - `NASA Ames Stereo Pipeline `_ Software for creating terrain models and ortho images from planetary stereo images. (Apache 2.0) @@ -44,23 +45,24 @@ Free and open source - `NextGIS Web `_ Server-side Web GIS and a framework for storage, visualization and permissions management of all kinds - `Ogr2 GUI `_ Graphical user interface for ogr2ogr - `OpenCPN `_ A concise ChartPlotter/Navigator. A cross-platform ship-borne GUI application. +- `OpenDataCube `_ FOSS software package that simplifies the management and analysis of large amounts of satellite imagery and other Earth observation data. - `OpenEV `_ An OpenGL/GTK/Python based graphical viewer which exclusively uses GDAL for raster access. - `OFGT `_ a collection of utilities for multipurpose forest monitoring under the `Open Foris Initiative `_ Open Foris Initiative. - `OpenFLUID `_ a software platform for spatial modelling of landscapes dynamics - `OpenSceneGraph `_ 3D rendering engine with `osgdem `_ and `osgEarth `_ plugins. - `Opticks `_ an open source remote sensing application and development framework, with a GDAL plugin. - `Orfeo Toolbox (OTB) `_ a general remote sensing image processing library. -- `OSSIM `_ Another geospatial viewing and analysis environment which uses GDAL as one of several plugins. +- `OSSIM `_ Another geospatial viewing and analysis environment which uses GDAL as one of several plugins. - `PDAL `_ Point Cloud Data Abstraction Library - `pktools `_ open source (GPLv3) tools written in C++ for remote sensing image processing - `PNMapcalc `_ A raster map calculator with C-like scripting language. - `PostGIS `_ spatial database extender for PostgreSQL: The raster loader and many of the raster SQL functions rely on GDAL. - `PostgreSQL OGR Foreign Data Wrapper `_ Expose OGR layer as PostgreSQL foreign tables. -- `QGIS `_ A cross platform desktop GIS. -- `R `_ A free software environment for statistical computing and graphics, with bindings to GDAL via the rgdal package. +- `QGIS `_ A cross platform desktop GIS. +- `R `_ A free software environment for statistical computing and graphics, with bindings to GDAL via the rgdal package. - `Rasterio `_ Python library and command line utilities to read and write GDAL rasters. - `Rasterix `_ A cross platform open source utility to process raster data based on Qt and GDAL. -- `SAGA GIS `_ A free geographic information system (GIS), with a special 'Application Programming Interface' (API) for geographic data processing. +- `SAGA GIS `_ A free geographic information system (GIS), with a special 'Application Programming Interface' (API) for geographic data processing. - `SNAP `_ Sentinel Application Platform for Earth Observation processing and analysis. - `StarSpan `_ raster/vector analysis. - `t-rex `_ Vector tile server written in Rust. @@ -75,50 +77,46 @@ Proprietary license / Other - `Cadcorp SIS: `_ A Windows GIS with a GDAL and OGR plugins. - `Carmenta Engine `_ (previously known as SpatialAce): A GIS Rapid Application Development environment - `CARTO `_ A cloud mapping platform to analyze and visualize geospatial data. -- `Cartographica `_ Macintosh GIS package. - `CatchmentSIM `_ A Windows terrain analysis model for hydrologic applications. - `Daylon Leveller `_ A terrain/heightfield/bumpmap modeler - `Eonfusion `_ Analysis and visualization of time-varying spatial datasets integrated via true data fusion. -- `ERDAS ER Viewer `_ Image viewer for very large JPEG 2000 and ECW files. -- `ESRI ArcGIS 9.2+ `_ A popular GIS platform. +- `ERDAS ER Viewer `_ Image viewer for very large JPEG 2000 and ECW files. +- `ESRI ArcGIS Pro `_ A popular GIS platform. - `Eternix Blaze `_ Advanced geo-spatial visualization application and SDK. - `FalconView `_ Windows-based GIS platform with roots in military mission planning, now available as a free GIS visualization and analysis package. - `flighttrack `_ GPS track viewing and downloading software for Mac. - `FME `_ A GIS translator package includes a GDAL plugin. -- `GenGIS `_ Software for geospatial analysis of genetic data. +- `GenGIS `_ Software for geospatial analysis of genetic data. - `Geographic Imager `_ DEM / aerial / satellite image processing GIS plug-in for Adobe Photoshop, by Avenza Systems. -- `GeoDMS `_ A framework for building spatial calculation models. +- `GeoDMS `_ A framework for building spatial calculation models. - `GeoFusion `_ 3D visualization. -- `GeoView Pro `_ IOS mobile mapping application. - `Geoweb3d `_ A 3D virtual globe that provides on-the-fly, game-quality visualization of GIS data. - `Google Earth `_ A 3D world viewer. -- `GPSeismic `_ A suite of applications for seismic survey. -- `HydroDaVE Explorer `_ A web-enabled client that provides users an easy to use, secure, and reliable data management platform to efficiently manage, access, and analyze environmental data. +- `HydroDaVE Explorer `_ A web-enabled client that provides users an easy to use, secure, and reliable data management platform to efficiently manage, access, and analyze environmental data. - `IDRISI `_ A GIS and Image Processing Windows Desktop application. Uses GDAL to import/export/warp raster data. - `Infraworks `_ a BIM software for infrastructure project design, part of the Autodesk suite. - `iShare `_ Web data integration and publishing platform by Astun Technology. - `Makai Voyager `_ An advanced 3D/4D geospatial visualization platform. -- `MapInfo Professional `_ Desktop GIS and mapping application +- `MapInfo Professional `_ Desktop GIS and mapping application - `MapTiler `_ Generator of tiles for interactive maps and overlays made from raster images and geodata. -- `Maptitude Mapping Software `_ Desktop GIS and business mapping application +- `Maptitude Mapping Software `_ Desktop GIS and business mapping application - `MicroImages TNT `_ advanced software for geospatial analysis (Windows, Linux, Mac OS X and UNIX) -- `Micromine `_ A mining software solution that uses GDAL for reading/writing various geospatial file formats. +- `Micromine `_ A mining software solution that uses GDAL for reading/writing various geospatial file formats. - `Mirone `_ Matlab based package for geospatial, oceanographic and geophysical analysis of grids -- `Mygeodata Converter `_ Online converter of GDAL raster and OGR vector formats +- `MyGeodata Cloud `_ Online converter of GDAL raster and OGR vector formats - `OPALS `_ Orientation and Processing of Airborne Laser Scanning Data - `Procura `_ Landholding inspection system developed for the UK Homes and Communities Agency. GDAL is used for checking out background mapping. - `ScanMagic `_ Win32 application for visualization, analysis and processing of remote sensing data. -- `Scalable Algorithmics (SCALGO) `_ Software for efficiently constructing and performing computations on very large raster and TIN terrain models. -- `Scenomics `_ Software for building terrain databases uses GDAL for projection and data import/export. -- `scenProc `_ scenProc: A tool to create scenery for Microsoft Flight Simulator and Lockheed Martin Prepar3D by processing G -- `SeaView `_ A 3D GIS package for geophysical and hydrographical data (side scan sonar, subbottom profiler, magnetometer, multibeam, etc. +- `Scalable Algorithmics (SCALGO) `_ Software for efficiently constructing and performing computations on very large raster and TIN terrain models. +- `Scenomics `_ Software for building terrain databases uses GDAL for projection and data import/export. +- `scenProc `_ scenProc: A tool to create scenery for Microsoft Flight Simulator and Lockheed Martin Prepar3D by processing G +- `SeaView `_ A 3D GIS package for geophysical and hydrographical data (side scan sonar, subbottom profiler, magnetometer, multibeam, etc. - `SkylineGlobe `_ The Skyline suite of interactive applications allows you to build, view, query and analyze customized, virtual 3D landscapes. -- `SpacEyes3D `_ 3D visualization software for cartographic data. +- `SpacEyes3D `_ 3D visualization software for cartographic data. - `Spatial Manager `_ A product suite designed designed to manage spatial data in a simple, fast and inexpensive way. Uses GDAL to import/export data. - `TacitView `_ An imagery visualization and exploitation package for military intelligence. - `TatukGIS `_ Desktop GIS mapping and data editing application. - `Team Awareness Kit `_ Suite of georeferenced imagery and situational awareness tools developed for military planning and execution, now available for civilian use. -- `TerraGo Technologies `_ The GeoPDF file format is used to distribute and collaborate geospatial data and uses GDAL for data import/export. - `TerrainView `_ Interactive real-time 3D GIS Software. - `TransCAD GIS `_ Desktop Transportation Analysis Software - `TravTime `_ .NET Application for visualizing, processing and analyzing GPS data for travel time, speed, and de diff --git a/doc/source/spelling_wordlist.txt b/doc/source/spelling_wordlist.txt index e1447916c7b9..3f610118685b 100644 --- a/doc/source/spelling_wordlist.txt +++ b/doc/source/spelling_wordlist.txt @@ -19,6 +19,7 @@ acl ACL actinia ActiveX +adbc addalpha addCurve addfields @@ -130,7 +131,6 @@ autocommit autoconf Autoconf autocorrelation -autodetection Autodesk autodetect autodetected @@ -370,6 +370,7 @@ cid CInt circularstrings ClampRequests +clang ClassificationCode Clayers CleanTimeout @@ -614,6 +615,7 @@ describedby deserialization deserialize deserialized +deserializing desirabled dest destructor @@ -984,6 +986,7 @@ gdalbuildvrt gdalcompare gdalconst gdaldata +GDALDataset gdaldem gdaldriver gdalenhance @@ -1013,9 +1016,11 @@ gdalrasterblock gdalrc gdalsrsinfo gdaltest +GDALThreadLocalDatasetCache gdaltindex gdaltransform gdalvirtualmem +gdalvsi gdalwarp gdalwmscache gdb @@ -1351,6 +1356,7 @@ IdentificationTolerance identificator Identificator IDisposable +idofic Idrisi iDriver idx @@ -1392,6 +1398,7 @@ InfoFormat InfoOptions Informatisé Informix +InfraRed ing ini init @@ -1508,6 +1515,7 @@ KShortest kslikebase KSpread ktx +Ku Kubernetes Kumar Kuratomi @@ -1548,6 +1556,7 @@ libbsd libcf libcfitsio libcrypto +libcsf libcurl libCurl libdav @@ -1574,6 +1583,7 @@ libkdu libkea libkml Libkml +liblerc libltidsdk liblz libmdbodbc @@ -1672,8 +1682,6 @@ LSB lsbf Lucena Luminance -Luratech -Lurawave luts lvbag lwf @@ -1776,6 +1784,7 @@ minY MinZ Mipmaps MiraD +miramon mis mitab mkdir @@ -1850,6 +1859,7 @@ MultiPolygon multipolygons multiproc multiprocess +multireadtest multirecords multispectral multistring @@ -2047,6 +2057,7 @@ nRecurseDepth nRefCount nReqOrder nSampleStep +nScopeFlags nSecond nSize nSrcBufferAllocSize @@ -2401,6 +2412,7 @@ Placemark plaintext Plessis plmosaic +plscenes plscenesconf pM pnBufferSize @@ -2725,6 +2737,7 @@ RecordBatch RecordBatchAsNumpy recurse recursionLevel +redirections Redistributable reentrancy reentrant @@ -2832,6 +2845,7 @@ RPF rpr RRaster rrd +rsc rsiz rst rsync @@ -2930,6 +2944,7 @@ sig Sightlines signedness significants +Simmon sinc sizeBytes sizeKnown @@ -3132,6 +3147,7 @@ swi Swif swiftclient swq +sxf sym symlinked syntaxes @@ -3360,6 +3376,7 @@ UpdateFeature updateTime UpperLeftX UpperLeftY +upsampling upsert uri url @@ -3402,6 +3419,7 @@ vcpkg vct vcvars vdc +vdv vecror VectorInfo VectorInfoOptions @@ -3444,6 +3462,7 @@ vsiaz vsicached vsicrypt vsicurl +VSIFile VSIFOpen vsigs vsigz diff --git a/doc/source/sponsors/faq.rst b/doc/source/sponsors/faq.rst index 397610dd7292..7d4e04835a86 100644 --- a/doc/source/sponsors/faq.rst +++ b/doc/source/sponsors/faq.rst @@ -38,7 +38,7 @@ various levels start with the `Sustainable GDAL Sponsorship Prospectus`_. If you are interested, need help convincing your key decision-makers, or have any questions, don't hesitate to contact gdal-sponsors@osgeo.org. -.. _Sustainable GDAL Sponsorship Prospectus: https://gdal.org/sponsors/Sustainable%20GDAL%20Sponsorship%20Prospectus.pdf +.. _Sustainable GDAL Sponsorship Prospectus: ../_static/Sustainable%20GDAL%20Sponsorship%20Prospectus.pdf What is NumFOCUS and why is the project using that foundation rather than using OSGeo for this effort? ------------------------------------------------------------------------------------------------------ diff --git a/doc/source/sponsors/index.rst b/doc/source/sponsors/index.rst index 634c3721c7f7..0cdc1c2bdb65 100644 --- a/doc/source/sponsors/index.rst +++ b/doc/source/sponsors/index.rst @@ -88,6 +88,13 @@ the health of the project: :width: 150 px :target: https://www.koordinates.com + .. container:: horizontal-logo + + .. image:: ../../images/sponsors/logo-linz.png + :class: img-logos + :width: 150 px + :target: https://www.linz.govt.nz + .. container:: horizontal-logo .. image:: ../../images/sponsors/logo-mapgears.png @@ -127,6 +134,10 @@ the health of the project: `Kaplan Open Source Consulting `__ + .. container:: horizontal-logo + + `Phoenix LiDAR Systems, LLC `__ + .. container:: horizontal-logo `PIX4D `__ @@ -240,6 +251,8 @@ Related resources - `Sustainable GDAL Sponsorship Prospectus`_. - :ref:`Sponsoring frequently asked questions (FAQ) `. +- :ref:`rfc-80` +- :ref:`rfc-83` .. Source of the PDF is at https://docs.google.com/document/d/1yhMWeI_LgEXPUkngqOitqcKfp7ov6WsS41v5ulz-kd0/edit# diff --git a/doc/source/thanks.rst b/doc/source/thanks.rst new file mode 100644 index 000000000000..1616b3c089aa --- /dev/null +++ b/doc/source/thanks.rst @@ -0,0 +1,205 @@ +.. _thanks: + +================================================================================ +Thanks +================================================================================ + +As of 2024, GDAL has now a 26 year-long existence, and many individuals, companies, +and :ref:`sponsors` have contributed to its development and success. +While it is always difficult to properly acknowledge all contributions, a few +individuals particularly stand out: + +- `Frank Warmerdam `__, creator of GDAL, initial chair of its Project Steering Committee + (PSC) and maintainer from 1998 to 2012, founding member of OSGeo, and currently + Principal Engineer at Planet. + GDAL would not be what is is without his outstanding work. Support for GeoTIFF, + JPEG, PNG, VRT, Shapefile, CSV, PostGIS and dozens of other popular (or niche) + formats, as well as gdal_translate, gdalwarp, ogr2ogr and most other utilities + are all to be credited to Frank. + +- `Howard Butler `__, director of Hobu Inc., active on GDAL since 2004, contributor to + the Python SWIG bindings, PSC member, founding member of OSGeo. + Howard was the coordinator of the fundraising that lead to the advent of + GDAL 3 and PROJ 6, and since 2021, he has been instrumental in setting up the + GDAL Sponsorship Program and serves as its head, liaising with our sponsors + and NumFOCUS, and hosting GDAL contributor monthly meetings. + +- `Jukka Rahkonen `__, Chief IT Specialist at the National Land Survey of Finland, + power-user and long-time passionate of GDAL, PSC member. + Over the last 15 years, Jukka has been tirelessly helping users and triaging + reports on the issue tracker and other support forums. + +- `Even Rouault `__, involved since 2007, main maintainer since 2014, current PSC chair, + director of Spatialys. + Even has authored dozens of drivers (and happy to have managed to retire + a few of them!) and many enhancements. He has also been involved in code + modernization, extension of the regression test suite, continuous integration + and security efforts. + +Among `code contributors `__, +we want to acknowledge the key, past or current, documentation or code contributions +of the following persons: + +- `Ben Ahmed Daho Ali `__: SXF driver +- `Jorge Arevalo `__: PostGIS Raster driver +- `Dan Baston `__: modernization of the Python test suite and Python bindings. +- `Norman Barker `__: JPIPKAK and TileDB drivers, PSC member. +- `Dmitry Baryshnikov `__: SXF and CAD drivers and the GNM component. +- `Andrew Bell `__: gdal_viewshed enhancements. +- `Pete Bunting `__: KEA driver. +- `Ragi Yaser Burhum `__: FileGDB driver. +- Brian Case: LIBKML driver. +- `Victor Chernetsky `__: AmigoCloud driver. +- Benjamin Collins: SWIG Java bindings. +- Christopher Condit: OGR to KML conversion. +- `Nyall Dawson `__: GeoPackage, OpenFileGDB, ODBC/PGeo and OGR core enhancements. Past co-maintainer. +- `Jürgen Fischer `__: NAS driver. +- `Alessandro Furieri `__: Spatialite support in SQLite driver, enhancements in GML driver. +- `Andrea Giudiceandrea `__: documentation fixes +- `Ari Jolma `__: Author of (ex) SWIG Perl bindings. +- `Trent Hare `__: PDS, ISIS2 and ISIS3 drivers. +- `Björn Harrtell `__: FlatGeoBuf driver. +- `Thomas Hirsch `__: SOSI driver. +- François Hissel: Selafin driver. +- `Pirmin Kalberer `__: Interlis drivers. +- `Andrey Kiselev `__: BMP, HDF4, HDF5, L1B, MrSID and RMF support, gdal_grid, past PSC member. +- `Dan Jacobson `__: documentation enhancements. +- `Kor de Jong `__: PCRaster driver. +- `Peter A. Jonsson `__: Docker scripts enhancements. +- Chaitanya Kumar CH: past GDAL maintainer. +- `Martin Lambers `__: GTA driver. +- `Martin Landa `__: VFK driver. +- `Kikitte Lee `__: Two-Arm chains edge tracing algorithm of gdal_polygonize. +- `Alexandr Lisovenko `__: SXF driver +- `Mateusz Łoskot `__: GeoJSON driver, (ex) Windows CE support, past GDAL maintainer. +- `Ivan Lucena `__: Idrisi, Intergraph and Oracle drivers, (ex) Windows build scripts. +- `Hugo Mercier `__: marching square algorithm of gdal_contour +- `Idan Miara `__: gdal-utils Python package. +- `Martin Mikita `__: PDFium backend of the PDF driver. +- `Hiroshi Miura `__: Initial CMake build system. +- `Vincent Mora `__: WAsP driver +- `Daniel Morissette `__: CPL library, MapInfo .mif/.tab and Arc/Info vector coverage (AVC) support, PSC member. +- Denis Nadeau: netCDF support. +- `Markus Neteler `__: various contributions to GDAL documentation +- Adam Nowacki: WMS driver. +- Jens Oberender: KML driver. +- `Alessandro Pasotti `__: co-maintainer since 2022. +- `Kai Pastor `__: contributions to the CMake build system. +- `Abel Pau `__: MiraMon driver. +- `Matthew Perry `__: gdaldem +- Mark Phillips: TIGER driver. +- `Lucian Plesea `__: ESRIC and MRF drivers. +- `Petr Pridal `__: gdal2tiles utility. +- `Paul Ramsey `__: GeoPackage and FileGDB drivers. +- Bas Retsios: MSG driver. +- Didier Richard: Geoconcept driver. +- Kevin Ruland: SWIG bindings refactor. +- `Maxim Rylov `__: Hana driver. +- `Michael Scholz `__: OpenDRIVE driver. +- `Kurt Schwehr `__: code linting through the whole codebase, PSC member. +- `Avyav Kumar Singh `__: enhancements in the OGR geometry support, SFCGAL support. +- `Craig de Stigter `__: port of GDAL Python autotest suite to the pytest framework. +- `Michael Sumner `__: documentation enhancements, vrt:// enhancements. +- `Tamas Szekeres `__: SWIG CSharp bindings, gdal_viewshed, PSC member. +- `Alan Thomas `__: major enhancements in the DXF driver. +- `Etienne Tourigny `__: major enhancements in the netCDF driver. +- Philippe Vachon: COASP, GFF, JaxaPalsar, TSX drivers. +- Stephane Villeneuve: OGR Feature Style support, MapInfo .mif. +- `Yorick de Wid `__: LVBAG driver. +- Chris Yesson: gdaldem + +Graphical contributions: + +- Marin Byrne: for producing the current GDAL icon set (based on the earlier version by Martin Daly). +- Darek Krawczyk: for producing design of the initial GDAL Team Member t-shirt (based on Marin's and Martin's graphics). +- `Joe Morrison `__: for producing the new `GDAL t-shirt `__ + +Packaging: + +- Alpine Linux: `Holger Jaekel `__ +- Debian: `Bas Couwenberg `__, `Francesco Paolo Lovergine `__ +- Conda-Forge: `Filipe Fernandes `__, `Daryl Herzmann `__ and `others `__ +- Fedora: `Sandro Mani `__ +- GISInternals: `Tamas Szekeres `__ +- Homebrew: `GDAL Homebrew maintainers `__ +- MS4W: `Jeff McKenna `__ +- OpenBSD: `Landry Breuil `__ +- OSGeo4W: `Jürgen Fischer `__ +- netBSD: `Greg Troxel `__ +- Spack: `Adam J. Stewart `__ +- Ubuntu: `Angelos Tzotsos `__ +- vcpkg: `Kai Pastor `__ + +You can also consult `Frank Warmerdam's sponsors, acknowledgments and credits `__ for the period 1998-2010. + +.. below is an allow-list for spelling checker. + +.. spelling:word-list:: + Daho + Arevalo + Ragi + Yaser + Burhum + Chernetsky + Condit + Giudiceandrea + Björn + Harrtell + Hirsch + François + Hissel + Lambers + Landa + Kikitte + Alexandr + Lisovenko + Mercier + Mikita + Hiroshi + Miura + Mora + Markus + Neteler + Nowacki + Jens + Oberender + Passoti + Kai + Pau + Plesea + Pridal + Bas + Retsios + Didier + Rylov + Scholz + Etienne + Tourigny + Vachon + Stephane + Villeneuve + Yorick + Wid + Byrne + Daly + Darek + Krawczyk + Couwenberg + Herzmann + Filipe + Fernandes + Sandro + Angelos + Tzotzos + Landry + Breuil + Holger + Jaekel + Francesco + Paolo + Lovergine + netBSD + Troxel + Chaitanya + Kumar + CH diff --git a/doc/source/tutorials/index.rst b/doc/source/tutorials/index.rst index 0542ac9b7626..78b6f6633fbb 100644 --- a/doc/source/tutorials/index.rst +++ b/doc/source/tutorials/index.rst @@ -49,3 +49,24 @@ Projections and Spatial Reference Systems tutorial (OSR - OGRSpatialReference) :maxdepth: 1 osr_api_tut + +Workshops +--------- + +- `Raster and vector processing with GDAL `__, FOSS4G-Europe 2015, Even Rouault + +External tutorials +------------------ + +A Gentle Introduction to GDAL, by Robert Simmon ++++++++++++++++++++++++++++++++++++++++++++++++ + +1. `A Gentle Introduction to GDAL `__ +2. `Map Projections & gdalwarp `__ +3. `Geodesy & Local Map Projections `__ +4. `Working with Satellite Data `__ +5. `Shaded Relief `__ +6. `Visualizing Data `__ +7. `Transforming Data `__ +8. `Reading Scientific Data Formats `__ + diff --git a/doc/source/user/configoptions.rst b/doc/source/user/configoptions.rst index aa2bcaa0209c..3c9c4b7d8eaa 100644 --- a/doc/source/user/configoptions.rst +++ b/doc/source/user/configoptions.rst @@ -222,7 +222,10 @@ Performance and caching :program:`gdalwarp`. If its value is small (less than 100000), it is assumed to be measured in megabytes, otherwise in bytes. Alternatively, the value can be set to "X%" to mean X% - of the usable physical RAM. Note that this value is only consulted the first + of the usable physical RAM. + Since GDAL 3.11, the value of :config:`GDAL_CACHEMAX` may specify the + units directly (e.g., "500MB", "2GB"). + Note that this value is only consulted the first time the cache size is requested. To change this value programmatically during operation of the program it is better to use :cpp:func:`GDALSetCacheMax` (always in bytes) or or @@ -318,6 +321,9 @@ Performance and caching Set the size of the VSI cache. Be wary of large values for ``VSI_CACHE_SIZE`` when opening VRT datasources containing many source rasters, as this is a per-file cache. + Since GDAL 3.11, the value of ``VSI_CACHE_SIZE`` may be specified using + memory units (e.g., "25 MB"). + Driver management ^^^^^^^^^^^^^^^^^ @@ -421,7 +427,7 @@ General options option. - .. config:: CPL_VSIL_DEFLATE_CHUNK_SIZE - :default: 1 M + :default: 1M - .. config:: GDAL_DISABLE_CPLLOCALEC :choices: YES, NO @@ -610,7 +616,8 @@ Networking options :since: 2.3 Size of global least-recently-used (LRU) cache shared among all downloaded - content. + content. Value is assumed to represent bytes unless memory units are + specified (since GDAL 3.11). - .. config:: CPL_VSIL_CURL_USE_HEAD :choices: YES, NO @@ -626,6 +633,20 @@ Networking options Try to query quietly redirected URLs to Amazon S3 signed URLs during their validity period, so as to minimize round-trips. +- .. config:: CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT + :choices: YES, NO, IF_SAME_HOST + :default: IF_SAME_HOST + :since: 3.10 + + Determines if the HTTP ``Authorization`` header must be forwarded when + redirections are followed: + + - ``NO`` to always disable forwarding of Authorization header + - ``YES`` to always enable forwarding of Authorization header (was the + default value prior to GDAL 3.10) + - ``IF_SAME_HOST`` to enable forwarding of Authorization header only if + the redirection is to the same host. + - .. config:: CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE :choices: YES, NO @@ -644,6 +665,9 @@ Networking options :choices: :since: 2.3 + Value is assumed to represent bytes unless memory units are + specified (since GDAL 3.11). + - .. config:: GDAL_INGESTED_BYTES_AT_OPEN :since: 2.3 @@ -967,36 +991,41 @@ PROJ options - .. config:: CHECK_WITH_INVERT_PROJ :since: 1.7.0 + :default: NO Used by :source_file:`ogr/ogrct.cpp` and :source_file:`apps/gdalwarp_lib.cpp`. - This option can be used to control the behavior of gdalwarp when warping global + This option can be used to control the behavior of :program:`gdalwarp` when warping global datasets or when transforming from/to polar projections, which causes coordinate discontinuities. See http://trac.osgeo.org/gdal/ticket/2305. - The background is that PROJ does not guarantee that converting from src_srs to - dst_srs and then from dst_srs to src_srs will yield to the initial coordinates. + The background is that PROJ does not guarantee that converting from ``src_srs`` to + ``dst_srs`` and then from ``dst_srs`` to ``src_srs`` will yield the initial coordinates. This can lead to errors in the computation of the target bounding box of - gdalwarp, or to visual artifacts. + :program:`gdalwarp`, or to visual artifacts. - If CHECK_WITH_INVERT_PROJ option is not set, gdalwarp will check that the the + If :config:`CHECK_WITH_INVERT_PROJ` option is not set, :program:`gdalwarp` will check that the computed coordinates of the edges of the target image are in the validity area of the target projection. If they are not, it will retry computing them by - setting :config:`CHECK_WITH_INVERT_PROJ=TRUE` that forces ogrct.cpp to check the - consistency of each requested projection result with the invert projection. + setting :config:`CHECK_WITH_INVERT_PROJ=TRUE` that forces + :source_file:`ogr/ogrct.cpp` to check the consistency of each requested + projection result with the inverse projection. - If set to NO, gdalwarp will not attempt to use the invert projection. + If set to ``NO``, :program:`gdalwarp` will not attempt to use the inverse projection. - .. config:: THRESHOLD :since: 1.7.0 + :default: 0.1 for geographic SRS, 10000 otherwise Used by :source_file:`ogr/ogrct.cpp`. - Used in combination with :config:`CHECK_WITH_INVERT_PROJ=TRUE`. Define - the acceptable threshold used to check if the roundtrip from src_srs to - dst_srs and from dst_srs to srs_srs yield to the initial coordinates. The - value must be expressed in the units of the source SRS (typically degrees - for a geographic SRS, meters for a projected SRS) + Used in combination with :config:`CHECK_WITH_INVERT_PROJ=TRUE`. Defines + the acceptable threshold used to check if the round-trip from ``src_srs`` to + ``dst_srs`` and from ``dst_srs`` to ``srs_srs`` yields the initial coordinates. + The round-trip transformation will be considered successful if the ``x`` and ``y`` + values are both within :config:`THRESHOLD` of the original values. + The value must be expressed in the units of the source SRS (typically degrees + for a geographic SRS, meters for a projected SRS). - .. config:: OGR_ENABLE_PARTIAL_REPROJECTION :since: 1.8.0 diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst index c63c54f5a225..2da8d497352a 100644 --- a/doc/source/user/index.rst +++ b/doc/source/user/index.rst @@ -18,3 +18,4 @@ User oriented documentation coordinate_epoch configoptions gdal_python_utilities + security diff --git a/doc/source/user/multithreading.rst b/doc/source/user/multithreading.rst index a4263362a679..c4318bada342 100644 --- a/doc/source/user/multithreading.rst +++ b/doc/source/user/multithreading.rst @@ -4,8 +4,8 @@ Multi-threading =============== -GDAL API: re-entrant, but not thread-safe ------------------------------------------ +GDAL API: re-entrant, but (generally) not thread-safe +----------------------------------------------------- The exact meaning of the terms ``thread-safe`` or ``re-entrant`` is not fully standardized. We will use here the `QT definitions `__. @@ -43,6 +43,26 @@ that are not thread-safe. Those restrictions apply to the C and C++ ABI, and all languages bindings (unless they would take special precautions to serialize calls) +Thread-safe GDAL dataset instances for raster read-only use cases +----------------------------------------------------------------- + +.. versionadded:: 3.10 + +RFC 101 adds a new capability to open, or obtain, a thread-safe dataset from +any dataset, but only for raster read-only use cases. + +At open time, this can be done by passing ``GDAL_OF_RASTER | GDAL_OF_THREAD_SAFE`` +to :cpp:func:`GDALOpenEx` / :cpp:func:`GDALDataset::Open`. + +Given an existing GDALDataset* instance, :cpp:func:`GDALDataset::IsThreadSafe` +can be used to determine if it is thread-safe or not. If not, +:cpp:func:`GDALDataset::GetThreadSafeDataset` can be used. + +Note that the generic implementation of this capability involves opening one +dataset the first time a thread-safe dataset/raster band is accessed by a thread. +While this is an implementation detail that can be ignored to develop code, it is +important to note regarding potential performance impacts + GDAL block cache and multi-threading ------------------------------------ diff --git a/doc/source/user/raster_data_model.rst b/doc/source/user/raster_data_model.rst index 35b80ae79ca6..03af38ace48b 100644 --- a/doc/source/user/raster_data_model.rst +++ b/doc/source/user/raster_data_model.rst @@ -189,6 +189,21 @@ For satellite or aerial imagery the IMAGERY Domain may be present. It depends on - CLOUDCOVER: Cloud coverage. The value between 0 - 100 or 999 if not available - ACQUISITIONDATETIME: The image acquisition date time in UTC +Starting with GDAL 3.10, there also exists a raster band level IMAGERY metadata domain with the following items: + +- CENTRAL_WAVELENGTH_UM: Central Wavelength in micrometers. +- FWHM_UM: Full-width half-maximum (FWHM) in micrometers. + +Clients can get (resp. set) these metadata items with :cpp:func:`GDALRasterBand::GetMetadataItem()` +(resp. :cpp:func:`GDALRasterBand::SetMetadataItem()`).` + +They are specifically set by the :ref:`raster.sentinel2` and +:ref:`raster.envi` drivers (if corresponding metadata items are found in the ENVI header), +but may also be found in other drivers handling arbitrary GDAL metadata, such as +the one using the GDAL Persistent Auxiliary Mechanism (PAM / .aux.xml side car files) +or :ref:`raster.vrt` drivers. The :ref:`raster.gtiff` driver also supports serializing +and deserializing the band IMAGERY metadata domain in the ``GDAL_METADATA`` TIFF tag. + xml: Domains ++++++++++++ @@ -228,20 +243,48 @@ A raster band has the following properties: - An optional raster unit name. For instance, this might indicate linear units for elevation data. - A color interpretation for the band. This is one of: - * GCI_Undefined: the default, nothing is known. - * GCI_GrayIndex: this is an independent gray-scale image - * GCI_PaletteIndex: this raster acts as an index into a color table - * GCI_RedBand: this raster is the red portion of an RGB or RGBA image - * GCI_GreenBand: this raster is the green portion of an RGB or RGBA image - * GCI_BlueBand: this raster is the blue portion of an RGB or RGBA image - * GCI_AlphaBand: this raster is the alpha portion of an RGBA image - * GCI_HueBand: this raster is the hue of an HLS image - * GCI_SaturationBand: this raster is the saturation of an HLS image - * GCI_LightnessBand: this raster is the lightness of an HLS image - * GCI_CyanBand: this band is the cyan portion of a CMY or CMYK image - * GCI_MagentaBand: this band is the magenta portion of a CMY or CMYK image - * GCI_YellowBand: this band is the yellow portion of a CMY or CMYK image - * GCI_BlackBand: this band is the black portion of a CMYK image. + * GCI_Undefined / "Undefined": default, nothing is known. + * GCI_GrayIndex / "Gray": independent gray-scale image + * GCI_PaletteIndex / "Palette": this raster acts as an index into a color table + * GCI_RedBand / "Red": red portion of an RGB or RGBA image, or red spectral band [0.62 - 0.69 um] + * GCI_GreenBand/ "Green": green portion of an RGB or RGBA image, or green spectral band [0.51 - 0.60 um] + * GCI_BlueBand / "Blue": blue portion of an RGB or RGBA image, or blue spectral band [0.45 - 0.53 um] + * GCI_AlphaBand / "Alpha": alpha portion of an RGBA image + * GCI_HueBand / "Hue": hue of a HLS image + * GCI_SaturationBand / "Saturation": saturation of a HLS image + * GCI_LightnessBand / "Lightness": lightness of a HLS image + * GCI_CyanBand / "Cyan": cyan portion of a CMY or CMYK image + * GCI_MagentaBand / "Magenta": magenta portion of a CMY or CMYK image + * GCI_YellowBand / "Yellow": yellow portion of a CMY or CMYK image, or yellow spectral band [0.58 - 0.62 um] + * GCI_BlackBand / "Black": black portion of a CMYK image. + + Below values have been added in GDAL 3.10: + + * GCI_PanBand / "Pan": Panchromatic band [0.40 - 1.00 um] + * GCI_CoastalBand / "Coastal": Coastal band [0.40 - 0.45 um] + * GCI_RedEdgeBand / "RedEdge": Red-edge band [0.69 - 0.79 um] + * GCI_NIRBand / "NIR": Near-InfraRed (NIR) band [0.75 - 1.40 um] + * GCI_SWIRBand / "SWIR": Short-Wavelength InfraRed (SWIR) band [1.40 - 3.00 um] + * GCI_MWIRBand / "MWIR": Mid-Wavelength InfraRed (MWIR) band [3.00 - 8.00 um] + * GCI_LWIRBand / "LWIR": Long-Wavelength InfraRed (LWIR) band [8.00 - 15 um] + * GCI_TIRBand / "TIR": Thermal InfraRed (TIR) band (MWIR or LWIR) [3 - 15 um] + * GCI_OtherIRBand / "OtherIR": Other infrared band [0.75 - 1000 um] + * GCI_SAR_Ka_Band / "SAR_Ka": Synthetic Aperture Radar (SAR) Ka band [0.8 - 1.1 cm / 27 - 40 GHz] + * GCI_SAR_K_Band / "SAR_K": Synthetic Aperture Radar (SAR) K band [1.1 - 1.7 cm / 18 - 27 GHz] + * GCI_SAR_Ku_Band / "SAR_Ku": Synthetic Aperture Radar (SAR) Ku band [1.7 - 2.4 cm / 12 - 18 GHz] + * GCI_SAR_X_Band / "SAR_X": Synthetic Aperture Radar (SAR) X band [2.4 - 3.8 cm / 8 - 12 GHz] + * GCI_SAR_C_Band / "SAR_C": Synthetic Aperture Radar (SAR) C band [3.8 - 7.5 cm / 4 - 8 GHz] + * GCI_SAR_S_Band / "SAR_S": Synthetic Aperture Radar (SAR) S band [7.5 - 15 cm / 2 - 4 GHz] + * GCI_SAR_L_Band / "SAR_L": Synthetic Aperture Radar (SAR) L band [15 - 30 cm / 1 - 2 GHz] + * GCI_SAR_P_Band / "SAR_P": Synthetic Aperture Radar (SAR) P band [30 - 100 cm / 0.3 - 1 GHz] + + For spectral bands, the wavelength ranges are indicative only, and may vary + depending on sensors. The ``CENTRAL_WAVELENGTH_UM`` and ``FWHM_UM`` metadata + items in the band ``IMAGERY`` metadata domain of the raster band, when present, will + give more accurate characteristics. + + Values belonging to the IR domain are in the [GCI_IR_Start, GCI_IR_End] range. + Values belonging to the SAR domain are in the [GCI_SAR_Start, GCI_SAR_End] range. - A color table, described in more detail later. - Knowledge of reduced resolution overviews (pyramids) if available. diff --git a/doc/source/user/security.rst b/doc/source/user/security.rst new file mode 100644 index 000000000000..ae9a6d532b48 --- /dev/null +++ b/doc/source/user/security.rst @@ -0,0 +1,222 @@ +.. _security: + +================================================================================ +Security considerations +================================================================================ + +This page discusses some security issues that users or developers may face while +using GDAL. It can also serve as a check-list of items to take care of, for +developers coding new drivers. + +While GDAL maintainers take a number of steps to limit the risk of software +vulnerabilities, GDAL has a large attack surface, because it deals with data in +a variety of file formats. + +.. note:: + + This page is not intended to be a comprehensive cook-book for being "safe" in all + circumstances, and should be considered as work-in-progress + that can benefit from continued feedback of people deploying GDAL. + Although they are specialists of the GDAL code base, GDAL maintainers are not + security experts. + +Classes of potential vulnerabilities +------------------------------------ + +- Arbitrary code execution with the privileges of the user running the GDAL + process. + +- Theft, tampering or destruction of data. + +- Denial of Service : abortion of a process, high consumption of CPU, memory, + I/O resource. + +- Unwanted network access. + +Causes +------ + +- Software bugs - in GDAL code itself, or in third-party dependencies - related + to code that processes user data. Common defects can be: + + * stack or heap buffer overflows, potentially leading to arbitrary code + execution. + + * excessive memory allocation + + * infinite, or very long, loops in code + +- Software functionalities themselves, depending on the context of use, can + be a source of vulnerabilities. Consult :ref:`security_known_issues` below. + +Situations at risk +------------------ + +The following are examples of situations where a user may process untrusted data +that has been crafted to trigger a vulnerability: + +- web services accepting input files provided by a client, + +- desktop use of GDAL where an hostile party manages to convince the victim + user to process hostile data. + +Mitigation +---------- + +- Upgrade to the latest versions of GDAL and its dependencies that might contain + bug fixes for some vulnerabilities. + +- Build GDAL with the hardening options of compilers, e.g. with -D_FORTIFY_SOURCE=2 + (some Linux distributions turn on it by default), to minimize the effect of + buffer overflows. + +- Restrict access to the part of the file system that are only needed. The ``​chroot`` + mechanism, or other sand-boxing solutions, might be a technical solution for this. + +- Compile only the subset of drivers needed. The ``GDAL_ENABLE_DRIVER_{name}`` + or ``OGR_ENABLE_DRIVER_{name}`` CMake build options can be used for that purpose. + +- Disable unneeded drivers at run-time by setting the :config:`GDAL_SKIP` + configuration option. + +- When network access is not needed, disable Curl at build time with the + ``GDAL_USE_CURL=OFF`` CMake option. + +- Process untrusted data in a dedicated user account with no access to other + local sensitive data (data files, passwords, encryption/signing keys, etc...). + Note that the mere act of opening a dataset with the GDAL/OGR API or utilities + is a form of processing. + +- For automatic services, place restrictions on the CPU time and memory + consumption allowed to the process using GDAL. Check the options of your + HTTP server. + +- Check the raster dimensions and number of bands just after opening a GDAL + driver and before processing it. Several GDAL drivers use the + :cpp:func:`GDALCheckDatasetDimensions` and :cpp:func:`GDALCheckBandCount` + functions to do early sanity checks, but user checks can also be useful. + For example, a dataset with huge raster dimensions but with a very small file + size might be suspicious (but not always, for example a VRT file, or highly + compressed data...) + +- Do not allow arbitrary arguments to be passed to command line utilities. + In particular ``--config GDAL_DRIVER_PATH xxx`` or ``--config OGR_DRIVER_PATH xxx`` + could be used to trigger arbitrary code execution for someone with write + access to some parts of the file system. Similarly, :config:`GDAL_VRT_ENABLE_PYTHON` + or :config:`GDAL_VRT_PYTHON_TRUSTED_MODULES` could be used to trigger hostile + Python code execution. + +- When possible, avoid using closed-source dependency libraries that cannot be + audited for vulnerabilities. + +.. _security_known_issues: + +Credential related issues +------------------------- + +GDAL network virtual file systems can access credentials needed to grant access +to remote resources, from the environment or local files. Those secrets are +stored in RAM using normal mechanisms. Consequently they could potentially be +recovered by untrusted code that would run in the same process as GDAL code. + +The same applies for connection strings to some drivers such as PostgreSQL, MySQL, etc. +which may include passwords. + +Known issues in API +------------------- + +- :cpp:func:`OGRSpatialReference::SetFromUserInput` accepts URLs by default + +Known issues in drivers +----------------------- + +General issues ++++++++++++++++ + +- Drivers do not always use file extensions to determine which file must be + handled by which driver (this is a feature in most situations). But, + for example, a VRT file might be disguised as a .tif, .png, or .jpg file. + So you cannot know which driver will handle a file by just looking at its + extension. Using ``gdalmanage identify the.file`` + (or :cpp:func:`GDALIdentifyDriver`) can be a way to know the + driver without attempting a full open of the file, but, drivers not having a + specialized implementation of the Identify() method will fall back to the Open() + method. + +- Drivers depending on third-party libraries whose code has been embedded in GDAL. + Binary builds might rely on the internal version, or the external version. + If using the internal version, they might use an obsolete version of the + third-party library that might contain known vulnerabilities. Potentially + concerned drivers are GTiff (libtiff, libgeotiff), PNG (libpng), GIF (giflib), + JPEG (libjpeg), PCRaster (libcsf), GeoJSON (libjson-c), MRF (liblerc). + An internal version of ZLib is also contained in GDAL sources. + Packagers of GDAL are recommended to use the external version of the libraries + when possible, so that security upgrades of those dependencies benefit to GDAL. + +- Drivers using GDALOpen()/GDALOpenEx()/OGROpen() internally cause other drivers + to be used (and their possible flaws exploited), without it being obvious at + first sight. VRT, MBTiles, KMLSuperOverlay, RasterLite, PCIDSK, PDF, RPFTOC, + RS2, WMS, WCS, WFS, OAPIF, OGCAPI and GTI are examples of drivers with this + behavior. + +- Drivers depending on downloaded data (HTTP, WMS, WCS, WFS, OAPIF, OGCAPI, + STACIT, STACTA, etc.). + +- XML based drivers: they might be subject to denial of service by + `​billion laugh-like `__ + attacks. Existing GDAL XML based drivers are thought to take defensive measures + against such patterns (starting with GDAL 3.9.3 for LVBAG and GMLAS drivers) + +- SQL injections: services that would accept untrusted SQL requests could trigger + SQL injection vulnerabilities in database-based drivers. + + +​GDAL MEM driver +++++++++++++++++ + +The opening syntax ``MEM:::DATAPOINTER=,PIXELS=,LINES=`` +can access any memory of the process. Feeding it with a random access can cause +a crash, or a read of unwanted virtual memory. The MEM driver is used by various algorithms +and drivers in creation mode (which is not vulnerable to the DATAPOINTER issue), +so completely disabling the driver might be detrimental to other areas of GDAL. +It is possible to define the GDAL_NO_OPEN_FOR_MEM_DRIVER *compilation* flag to +disable the ``MEM:::DATAPOINTER``` syntax only. + +​GDAL PDF driver +++++++++++++++++ + +The OGR_DATASOURCE creation option accepts a file name. So any OGR datasource, +and potentially any file (see OGR VRT) could be read through this option, and +its content embedded in the generated PDF. +Similarly for the COMPOSITION_FILE creation option. + +​GDAL VRT driver +++++++++++++++++ + +It can be used to access any valid GDAL dataset. If a hostile party, with +knowledge of the location on the filesystem of a valid GDAL dataset, convinces +a user to run gdal_translate a VRT file and give it back the result, +it might be able to steal data. That could potentially be able for a web service +accepting data from the user, converting it, and sending back the result. + +The VRTRawRasterBand mechanism can read any file (not necessarily a +valid GDAL dataset) accessible, which can extend the scope of the above +mentioned issue. + +The VRTDerivedRasterBand mechanism can use Pixel functions written in Python, +directly embedded in a VRT file, or pointing to external Python code. By +default this mechanism is disabled, to avoid arbitrary code execution. +Consult :ref:`raster_vrt_security_implications` for more details. + +/vsicurl/ (and associated network-capable virtual file systems) filenames can be +used, thus causing remote data to be downloaded. + +​GDAL GTI driver +++++++++++++++++ + +Same issues as the GDAL VRT driver. + +​OGR VRT driver ++++++++++++++++ + +Similar issues as the GDAL VRT driver. ```` could be used to modify data. diff --git a/doc/source/user/sql_sqlite_dialect.rst b/doc/source/user/sql_sqlite_dialect.rst index 0a539e115d26..0c2367495636 100644 --- a/doc/source/user/sql_sqlite_dialect.rst +++ b/doc/source/user/sql_sqlite_dialect.rst @@ -120,16 +120,14 @@ between double quotes, the internal double quotes must be escaped with \\ Geometry field ++++++++++++++ -The ``GEOMETRY`` special field represents the geometry of the feature -returned by OGRFeature::GetGeometryRef(). It can be explicitly specified -in the result column list of a SELECT, and is automatically selected if the -* wildcard is used. +Geometry fields can be explicitly specified in the result column list of a SELECT, +or automatically selected if the * wildcard is used. For OGR layers that have a non-empty geometry column name (generally for RDBMS datasources), as returned by OGRLayer::GetGeometryColumn(), the name of the geometry special field -in the SQL statement will be the name of the geometry column of the underlying OGR layer. +in the SQL statement must be the name of the geometry column of the underlying OGR layer. If the name of the geometry column in the source layer is empty, like with shapefiles etc., -the name to use in the SQL statement is always "geometry". Here we'll use it case-insensitively +the name to use in the SQL statement must be "geometry". Here we'll use it case-insensitively (as all field names are in a SELECT statement): .. code-block:: @@ -169,14 +167,6 @@ so use the name ``rowid``. Starting with GDAL 3.8, if the layer has a named FID column (:cpp:func:`OGRLayer::GetFIDColumn` != ""), this name may also be used. -The field wildcard expansions will not include the feature id, but it may be -explicitly included using a syntax like: - -.. code-block:: - - SELECT ROWID, * FROM nation - - The field wildcard expansions will not include the feature id, but it may be explicitly included using a syntax like: @@ -208,8 +198,18 @@ Statistics functions In addition to standard COUNT(), SUM(), AVG(), MIN(), MAX(), the following aggregate functions are available: -- STDDEV_POP: (GDAL >= 3.10) numerical population standard deviation. -- STDDEV_SAMP: (GDAL >= 3.10) numerical `sample standard deviation `__ +- ``STDDEV_POP(numeric_value)``: (GDAL >= 3.10) numerical population standard deviation. +- ``STDDEV_SAMP(numeric_value)``: (GDAL >= 3.10) numerical `sample standard deviation `__ + +Ordered-set aggregate functions ++++++++++++++++++++++++++++++++ + +The following aggregate functions are available. Note that they require to allocate an amount of memory proportional to the number of selected rows (for ``MEDIAN``, ``PERCENTILE`` and ``PERCENTILE_CONT``) or to the number of values (for ``MODE``). + +- ``MEDIAN(numeric_value)``: (GDAL >= 3.10) (continuous) median (equivalent to ``PERCENTILE(numeric_value, 50)``). NULL values are ignored. +- ``PERCENTILE(numeric_value, percentage)``: (GDAL >= 3.10) (continuous) percentile, with percentage between 0 and 100 (equivalent to ``PERCENTILE_CONT(numeric_value, percentage / 100)``). NULL values are ignored. +- ``PERCENTILE_CONT(numeric_value, fraction)``: (GDAL >= 3.10) (continuous) percentile, with fraction between 0 and 1. NULL values are ignored. +- ``MODE(value)``: (GDAL >= 3.10): mode, i.e. most frequent input value (strings and numeric values are supported), arbitrarily choosing the first one if there are multiple equally-frequent results. NULL values are ignored. Spatialite SQL functions ++++++++++++++++++++++++ diff --git a/doc/source/user/virtual_file_systems.rst b/doc/source/user/virtual_file_systems.rst index 860025e30452..e553ff39453e 100644 --- a/doc/source/user/virtual_file_systems.rst +++ b/doc/source/user/virtual_file_systems.rst @@ -413,6 +413,11 @@ As an alternative, starting with GDAL 3.6, the :config:`GDAL_HTTP_HEADERS` configuration option can also be used to specify headers. :config:`CPL_CURL_VERBOSE=YES` allows one to see them and more, when combined with ``--debug``. +Starting with GDAL 3.10, the ``Authorization`` header is no longer automatically +forwarded when redirections are followed. +That behavior can be configured by setting the +:config:`CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT` configuration option. + Starting with GDAL 2.3, the :config:`GDAL_HTTP_MAX_RETRY` (number of attempts) and :config:`GDAL_HTTP_RETRY_DELAY` (in seconds) configuration option can be set, so that request retries are done in case of HTTP errors 429, 502, 503 or 504. Starting with GDAL 3.6, the following configuration options control the TCP keep-alive functionality (cf https://daniel.haxx.se/blog/2020/02/10/curl-ootw-keepalive-time/ for a detailed explanation): @@ -624,9 +629,10 @@ Since GDAL 3.1, the :cpp:func:`VSIRmdirRecursive` operation is supported (using The :config:`CPL_VSIS3_CREATE_DIR_OBJECT` configuration option can be set to NO to prevent the :cpp:func:`VSIMkdir` operation from creating an empty object with the name of the directory terminated with a slash directory. By default GDAL creates such object, so that empty directories can be modeled, but this may cause compatibility problems with applications that do not expect such empty objects. - Starting with GDAL 3.5, profiles that use IAM role assumption (see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html) are handled. The ``role_arn`` and ``source_profile`` keywords are required in such profiles. The optional ``external_id``, ``mfa_serial`` and ``role_session_name`` can be specified. ``credential_source`` is not supported currently. +Support for AWS Single-Sign On (AWS IAM Identity Center) parameters in ``~/.aws/config`` and cached SSO files in ``~/.aws/sso/cache`` is implemented since GDAL 3.10.1. + .. _vsis3_imds: /vsis3/ and AWS Instance Metadata Service (IMDS) diff --git a/docker/README.md b/docker/README.md index dc826714445f..74d3a1d865a3 100644 --- a/docker/README.md +++ b/docker/README.md @@ -47,7 +47,7 @@ See [alpine-normal/Dockerfile](alpine-normal/Dockerfile) # Ubuntu based Ubuntu version: -* 24.04 for GDAL 3.9 +* 24.04 for GDAL 3.9 and 3.10 * 22.04 for GDAL 3.6, 3.7 and 3.8 * 20.04 for GDAL 3.4 and 3.5 @@ -100,11 +100,11 @@ If you are getting a ``: arena 0 background thread creation failed (1) # Images of releases -Tagged images of recent past releases are available. The last ones (at time of writing) are for GDAL 3.9.2 and PROJ 9.4.1, for linux/amd64 and linux/arm64: -* ghcr.io/osgeo/gdal:alpine-small-3.9.2 -* ghcr.io/osgeo/gdal:alpine-normal-3.9.2 -* ghcr.io/osgeo/gdal:ubuntu-small-3.9.2 -* ghcr.io/osgeo/gdal:ubuntu-full-3.9.2 +Tagged images of recent past releases are available. The last ones (at time of writing) are for GDAL 3.10.0 and PROJ 9.5.0, for linux/amd64 and linux/arm64: +* ghcr.io/osgeo/gdal:alpine-small-3.10.0 +* ghcr.io/osgeo/gdal:alpine-normal-3.10.0 +* ghcr.io/osgeo/gdal:ubuntu-small-3.10.0 +* ghcr.io/osgeo/gdal:ubuntu-full-3.10.0 ## Multi-arch Images diff --git a/docker/alpine-normal/Dockerfile b/docker/alpine-normal/Dockerfile index 76c6e0373217..b68d001eef16 100644 --- a/docker/alpine-normal/Dockerfile +++ b/docker/alpine-normal/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ## # osgeo/gdal:alpine-normal @@ -6,11 +8,13 @@ # or licensed under MIT (LICENSE.TXT) Copyright 2019 Even Rouault ARG ALPINE_VERSION=3.20 -FROM alpine:${ALPINE_VERSION} as builder +FROM alpine:${ALPINE_VERSION} AS builder # Derived from osgeo/proj by Howard Butler LABEL maintainer="Even Rouault " +ENV HOME="/root" + # Setup build env for PROJ RUN apk add --no-cache wget curl unzip cmake make libtool autoconf automake pkgconfig gcc g++ sqlite sqlite-dev tiff-dev @@ -62,6 +66,7 @@ RUN apk add --no-cache \ make \ mariadb-connector-c-dev \ netcdf-dev \ + ninja-build \ odbc-cpp-wrapper-dev \ ogdi-dev \ openexr-dev \ @@ -77,6 +82,7 @@ RUN apk add --no-cache \ py3-setuptools \ python3-dev \ qhull-dev \ + rsync \ sfcgal-dev \ snappy-dev \ sqlite-dev \ @@ -90,6 +96,9 @@ RUN apk add --no-cache \ zstd-dev \ && mkdir -p /build_thirdparty/usr/lib +# Ninja is not in the default path on Alpine. +ENV PATH=/usr/lib/ninja-build/bin:$PATH + RUN if test "$(uname -m)" = "x86_64"; then ( \ apk add --no-cache librasterlite2-dev \ ); fi @@ -99,7 +108,7 @@ ARG HDF4_VERSION=4.2.16 RUN if test "${HDF4_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ apk add --no-cache byacc flex portablexdr-dev \ && mkdir hdf4 \ - && wget -q https://support.hdfgroup.org/ftp/HDF/releases/HDF${HDF4_VERSION}/src/hdf-${HDF4_VERSION}.tar.gz -O - \ + && curl -L -fsS https://support.hdfgroup.org/ftp/HDF/releases/HDF${HDF4_VERSION}/src/hdf-${HDF4_VERSION}.tar.gz \ | tar xz -C hdf4 --strip-components=2 \ && cd hdf4 \ && LDFLAGS=-lportablexdr ./configure --prefix=/usr --enable-shared --disable-static \ @@ -117,14 +126,14 @@ RUN if test "${HDF4_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ # Build libOpenDRIVE ARG OPENDRIVE_VERSION=0.6.0-gdal RUN if test "${OPENDRIVE_VERSION}" != ""; then ( \ - wget -q https://github.com/DLR-TS/libOpenDRIVE/archive/refs/tags/${OPENDRIVE_VERSION}.tar.gz \ + curl -LO -fsS https://github.com/DLR-TS/libOpenDRIVE/archive/refs/tags/${OPENDRIVE_VERSION}.tar.gz \ && tar xzf ${OPENDRIVE_VERSION}.tar.gz \ && rm -f ${OPENDRIVE_VERSION}.tar.gz \ && cd libOpenDRIVE-${OPENDRIVE_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ + && cmake . -G Ninja -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/ \ - && make -j$(nproc) \ - && make install \ + && ninja \ + && ninja install \ && mkdir -p /build_thirdparty/usr/lib \ && cp -P /usr/lib/libOpenDrive*.so* /build_thirdparty/usr/lib \ && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ @@ -132,41 +141,46 @@ RUN if test "${OPENDRIVE_VERSION}" != ""; then ( \ && rm -rf libOpenDRIVE-${OPENDRIVE_VERSION} \ ); fi -RUN apk add --no-cache rsync ccache ARG RSYNC_REMOTE +ARG WITH_CCACHE # Build PROJ ARG PROJ_VERSION=master -RUN mkdir proj \ - && wget -q https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz -O - \ +RUN --mount=type=cache,id=alpine-normal-proj,target=$HOME/.cache \ + mkdir proj \ + && curl -L -fsS https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz \ | tar xz -C proj --strip-components=1 \ && cd proj \ && if test "${RSYNC_REMOTE}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/proj/$(uname -m)/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/proj/$(uname -m)/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ export CC="ccache gcc"; \ export CXX="ccache g++"; \ - mkdir -p "$HOME/.ccache"; \ - export PROJ_DB_CACHE_DIR="$HOME/.ccache"; \ + export PROJ_DB_CACHE_PARAM="-DPROJ_DB_CACHE_DIR=$HOME/.cache"; \ ccache -M 100M; \ fi \ # IPO disabled since it crashes with gcc 13.2.1 && cmake . \ + -G Ninja \ -DBUILD_SHARED_LIBS=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DENABLE_IPO=OFF \ -DBUILD_TESTING=OFF \ - && make -j$(nproc) \ - && make install \ - && make install DESTDIR="/build_proj" \ + $PROJ_DB_CACHE_PARAM \ + && ninja \ + && ninja install \ + && DESTDIR="/build_proj" ninja install \ && if test "${RSYNC_REMOTE}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/proj/$(uname -m)/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/proj/$(uname -m)/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -177,30 +191,33 @@ RUN mkdir proj \ # Build spatialite ARG SPATIALITE_VERSION=5.1.0 -RUN if test "${SPATIALITE_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ - wget -q https://www.gaia-gis.it/gaia-sins/libspatialite-sources/libspatialite-${SPATIALITE_VERSION}.tar.gz \ +RUN --mount=type=cache,id=alpine-normal-spatialite,target=$HOME/.cache \ + if test "${SPATIALITE_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ + curl -LO -fsS https://www.gaia-gis.it/gaia-sins/libspatialite-sources/libspatialite-${SPATIALITE_VERSION}.tar.gz \ && tar xzf libspatialite-${SPATIALITE_VERSION}.tar.gz \ && rm -f libspatialite-${SPATIALITE_VERSION}.tar.gz \ && cd libspatialite-${SPATIALITE_VERSION} \ && apk add --no-cache minizip-dev \ && if test "${RSYNC_REMOTE}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/spatialite/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/spatialite/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ export CC="ccache gcc"; \ export CXX="ccache g++"; \ - mkdir -p "$HOME/.ccache"; \ ccache -M 100M; \ fi \ && ./configure --prefix=/usr --disable-static --disable-rttopo \ && make -j$(nproc) \ && make install \ && if test "${RSYNC_REMOTE}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/spatialite/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/spatialite/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -219,7 +236,8 @@ ARG GDAL_RELEASE_DATE ARG GDAL_BUILD_IS_RELEASE ARG GDAL_REPOSITORY=OSGeo/gdal -RUN if test "${GDAL_VERSION}" = "master"; then \ +RUN --mount=type=cache,id=alpine-normal-gdal,target=$HOME/.cache \ + if test "${GDAL_VERSION}" = "master"; then \ export GDAL_VERSION=$(curl -Ls https://api.github.com/repos/${GDAL_REPOSITORY}/commits/HEAD -H "Accept: application/vnd.github.VERSION.sha"); \ export GDAL_RELEASE_DATE=$(date "+%Y%m%d"); \ fi \ @@ -231,13 +249,15 @@ RUN if test "${GDAL_VERSION}" = "master"; then \ && export LDFLAGS="-lportablexdr ${LDFLAGS}"; \ fi \ && mkdir gdal \ - && wget -q https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz -O - \ + && curl -L -fsS https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz \ | tar xz -C gdal --strip-components=1 \ && cd gdal \ && if test "${RSYNC_REMOTE}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/gdal/$(uname -m)/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/gdal/$(uname -m)/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ # Little trick to avoid issues with Python bindings printf "#!/bin/sh\nccache gcc \$*" > ccache_gcc.sh; \ chmod +x ccache_gcc.sh; \ @@ -245,12 +265,12 @@ RUN if test "${GDAL_VERSION}" = "master"; then \ chmod +x ccache_g++.sh; \ export CC=$PWD/ccache_gcc.sh; \ export CXX=$PWD/ccache_g++.sh; \ - mkdir -p "$HOME/.ccache"; \ ccache -M 1G; \ fi \ && mkdir build \ && cd build \ && cmake .. \ + -G Ninja \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=Release \ -DGDAL_USE_TIFF_INTERNAL=ON \ @@ -260,16 +280,17 @@ RUN if test "${GDAL_VERSION}" = "master"; then \ -DBUILD_TESTING=OFF \ -DOpenDrive_DIR=/usr/lib/ \ -DOGR_ENABLE_DRIVER_XODR_PLUGIN=TRUE \ - && make -j$(nproc) \ - && make install DESTDIR="/build" \ - && (make -j$(nproc) multireadtest && cp apps/multireadtest /build/usr/bin) \ + && ninja \ + && DESTDIR="/build" ninja install \ + && (ninja multireadtest && cp apps/multireadtest /build/usr/bin) \ && cd .. \ && if test "${RSYNC_REMOTE}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/gdal/$(uname -m)/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/gdal/$(uname -m)/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -296,7 +317,7 @@ RUN if test "${GDAL_VERSION}" = "master"; then \ ;do rm $i; done) # Build final image -FROM alpine:${ALPINE_VERSION} as runner +FROM alpine:${ALPINE_VERSION} AS runner RUN date diff --git a/docker/alpine-small/Dockerfile b/docker/alpine-small/Dockerfile index e4fc732b8d77..1a19574efb44 100644 --- a/docker/alpine-small/Dockerfile +++ b/docker/alpine-small/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ## # osgeo/gdal:alpine-small @@ -6,93 +8,103 @@ # or licensed under MIT (LICENSE.TXT) Copyright 2019 Even Rouault ARG ALPINE_VERSION=3.20 -FROM alpine:${ALPINE_VERSION} as builder +FROM alpine:${ALPINE_VERSION} AS builder # Derived from osgeo/proj by Howard Butler LABEL maintainer="Even Rouault " +ENV HOME="/root" + # Setup build env for PROJ RUN apk add --no-cache wget curl unzip make libtool autoconf automake pkgconfig g++ sqlite sqlite-dev # For PROJ and GDAL RUN apk add --no-cache \ + ccache \ + cmake ninja-build \ linux-headers \ curl-dev tiff-dev \ zlib-dev zstd-dev lz4-dev libdeflate-dev libarchive-dev \ - libjpeg-turbo-dev libpng-dev libwebp-dev expat-dev postgresql-dev openjpeg-dev + libjpeg-turbo-dev libpng-dev libwebp-dev expat-dev \ + postgresql-dev \ + rsync \ + openjpeg-dev + +# Ninja is not in the default path on Alpine. +ENV PATH=/usr/lib/ninja-build/bin:$PATH # Build openjpeg #ARG OPENJPEG_VERSION=2.3.1 RUN if test "${OPENJPEG_VERSION}" != ""; then ( \ - apk add --no-cache cmake \ - && wget -q https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \ + curl -LO -fsS https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \ && tar xzf v${OPENJPEG_VERSION}.tar.gz \ && rm -f v${OPENJPEG_VERSION}.tar.gz \ && cd openjpeg-${OPENJPEG_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \ + && cmake . -G Ninja -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ - && make -j$(nproc) \ - && make install \ + && ninja \ + && ninja install \ && mkdir -p /build_thirdparty/usr/lib \ && cp -P /usr/lib/libopenjp2*.so* /build_thirdparty/usr/lib \ && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ && cd .. \ && rm -rf openjpeg-${OPENJPEG_VERSION} \ - && apk del cmake \ ); fi -RUN apk add --no-cache rsync ccache - ARG PROJ_DATUMGRID_LATEST_LAST_MODIFIED RUN \ mkdir -p /build_projgrids/usr/share/proj \ - && curl -LOs http://download.osgeo.org/proj/proj-datumgrid-latest.zip \ + && curl -LO -fsS http://download.osgeo.org/proj/proj-datumgrid-latest.zip \ && unzip -q -j -u -o proj-datumgrid-latest.zip -d /build_projgrids/usr/share/proj \ && rm -f *.zip ARG RSYNC_REMOTE +ARG WITH_CCACHE # Build PROJ ARG PROJ_VERSION=master -RUN mkdir proj \ - && apk add --no-cache cmake \ - && wget -q https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz -O - \ +RUN --mount=type=cache,id=alpine-small-proj,target=$HOME/.cache \ + mkdir proj \ + && curl -L -fsS https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz \ | tar xz -C proj --strip-components=1 \ && cd proj \ && if test "${RSYNC_REMOTE}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/proj/$(uname -m)/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/proj/$(uname -m)/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ export CC="ccache gcc"; \ export CXX="ccache g++"; \ - mkdir -p "$HOME/.ccache"; \ - export PROJ_DB_CACHE_DIR="$HOME/.ccache"; \ + export PROJ_DB_CACHE_PARAM="-DPROJ_DB_CACHE_DIR=$HOME/.cache"; \ ccache -M 100M; \ fi \ # IPO disabled since it crashes with gcc 13.2.1 && cmake . \ + -G Ninja \ -DBUILD_SHARED_LIBS=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DENABLE_IPO=OFF \ -DBUILD_TESTING=OFF \ - && make -j$(nproc) \ - && make install \ - && make install DESTDIR="/build_proj" \ + $PROJ_DB_CACHE_PARAM \ + && ninja \ + && ninja install \ + && DESTDIR="/build_proj" ninja install \ && if test "${RSYNC_REMOTE}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/proj/$(uname -m)/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/proj/$(uname -m)/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ && cd .. \ && rm -rf proj \ && for i in /build_proj/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && for i in /build_proj/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && apk del cmake + && for i in /build_proj/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done # Build GDAL ARG GDAL_VERSION=master @@ -100,44 +112,47 @@ ARG GDAL_RELEASE_DATE ARG GDAL_BUILD_IS_RELEASE ARG GDAL_REPOSITORY=OSGeo/gdal -RUN if test "${GDAL_VERSION}" = "master"; then \ +RUN --mount=type=cache,id=alpine-small-gdal,target=$HOME/.cache \ + if test "${GDAL_VERSION}" = "master"; then \ export GDAL_VERSION=$(curl -Ls https://api.github.com/repos/${GDAL_REPOSITORY}/commits/HEAD -H "Accept: application/vnd.github.VERSION.sha"); \ export GDAL_RELEASE_DATE=$(date "+%Y%m%d"); \ fi \ - && apk add --no-cache cmake \ && if test "x${GDAL_BUILD_IS_RELEASE}" = "x"; then \ export GDAL_SHA1SUM=${GDAL_VERSION}; \ fi \ && if test "${RSYNC_REMOTE}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/gdal/$(uname -m)/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/gdal/$(uname -m)/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ export CC="ccache gcc"; \ export CXX="ccache g++"; \ - mkdir -p "$HOME/.ccache"; \ ccache -M 1G; \ fi \ && mkdir gdal \ - && wget -q https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz -O - \ + && curl -L -fsS https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz \ | tar xz -C gdal --strip-components=1 \ && cd gdal \ && mkdir build \ && cd build \ && cmake .. \ + -G Ninja \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=Release \ -DGDAL_USE_TIFF_INTERNAL=ON \ -DGDAL_USE_GEOTIFF_INTERNAL=ON \ -DBUILD_TESTING=OFF \ - && make -j$(nproc) \ - && make install DESTDIR="/build" \ + && ninja \ + && DESTDIR="/build" ninja install \ && cd .. \ && if test "${RSYNC_REMOTE}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/gdal/$(uname -m)/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/gdal/$(uname -m)/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -148,11 +163,10 @@ RUN if test "${GDAL_VERSION}" = "master"; then \ && mv /build/usr/include/gdal_version.h /build_gdal_version_changing/usr/include \ && mv /build/usr/bin /build_gdal_version_changing/usr \ && for i in /build_gdal_version_changing/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && for i in /build_gdal_version_changing/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && apk del cmake + && for i in /build_gdal_version_changing/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done # Build final image -FROM alpine:${ALPINE_VERSION} as runner +FROM alpine:${ALPINE_VERSION} AS runner RUN date diff --git a/docker/ubuntu-full/Dockerfile b/docker/ubuntu-full/Dockerfile index 685d1686ed7b..30f71c7941c5 100644 --- a/docker/ubuntu-full/Dockerfile +++ b/docker/ubuntu-full/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ## # osgeo/gdal:ubuntu-full @@ -8,16 +10,23 @@ ARG BASE_IMAGE=ubuntu:24.04 ARG TARGET_BASE_IMAGE=ubuntu:24.04 -FROM $BASE_IMAGE as builder +FROM $BASE_IMAGE AS builder # Derived from osgeo/proj by Howard Butler LABEL maintainer="Even Rouault " +ENV HOME="/root" + ARG TARGET_ARCH= RUN echo ${TARGET_ARCH} COPY ./bh-set-envvars.sh /buildscripts/bh-set-envvars.sh -RUN . /buildscripts/bh-set-envvars.sh \ +RUN rm -f /etc/apt/apt.conf.d/docker-clean \ + && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \ + && echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retries +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && if test "${TARGET_ARCH}" != ""; then \ rm -f /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources \ && echo "deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe" >> /etc/apt/sources.list \ @@ -31,24 +40,28 @@ RUN . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y g++-13-${GCC_ARCH}-linux-gnu \ && ln -s ${GCC_ARCH}-linux-gnu-gcc-13 /usr/bin/${GCC_ARCH}-linux-gnu-gcc \ - && ln -s ${GCC_ARCH}-linux-gnu-g++-13 /usr/bin/${GCC_ARCH}-linux-gnu-g++ \ - && rm -rf /var/lib/apt/lists/*; \ + && ln -s ${GCC_ARCH}-linux-gnu-g++-13 /usr/bin/${GCC_ARCH}-linux-gnu-g++; \ fi # Setup build env for PROJ USER root -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \ - build-essential ca-certificates \ - git make cmake wget unzip libtool automake \ + build-essential ca-certificates ccache\ + git make ninja-build cmake wget unzip libtool automake \ zlib1g-dev${APT_ARCH_SUFFIX} libsqlite3-dev${APT_ARCH_SUFFIX} pkg-config sqlite3 libcurl4-openssl-dev${APT_ARCH_SUFFIX} \ libtiff-dev${APT_ARCH_SUFFIX} \ - && rm -rf /var/lib/apt/lists/* + patchelf \ + rsync ARG JAVA_VERSION=17 # Setup build env for GDAL -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \ libopenjp2-7-dev${APT_ARCH_SUFFIX} libcairo2-dev${APT_ARCH_SUFFIX} \ @@ -68,22 +81,41 @@ RUN . /buildscripts/bh-set-envvars.sh \ libbrotli-dev${APT_ARCH_SUFFIX} \ libarchive-dev${APT_ARCH_SUFFIX} \ libaec-dev${APT_ARCH_SUFFIX} \ - libavif-dev${APT_ARCH_SUFFIX} \ - && rm -rf /var/lib/apt/lists/* + libavif-dev${APT_ARCH_SUFFIX} -# Build likbkea +ARG RSYNC_REMOTE +ARG WITH_CCACHE + +# Build libkea ARG KEA_VERSION=1.5.2 -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-kealib,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && wget -q https://github.com/ubarsc/kealib/archive/kealib-${KEA_VERSION}.zip \ && unzip -q kealib-${KEA_VERSION}.zip \ && rm -f kealib-${KEA_VERSION}.zip \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/kealib/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd kealib-kealib-${KEA_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ + && cmake . -G Ninja $CCACHE_PARAM -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr -DHDF5_INCLUDE_DIR=/usr/include/hdf5/serial \ -DHDF5_LIB_PATH=/usr/lib/${GCC_ARCH}-linux-gnu/hdf5/serial -DLIBKEA_WITH_GDAL=OFF \ - && make -j$(nproc) \ - && make install DESTDIR="/build_thirdparty" \ - && make install \ + && ninja \ + && DESTDIR="/build_thirdparty" ninja install \ + && ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/kealib/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && cd .. \ && rm -rf kealib-kealib-${KEA_VERSION} \ && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ @@ -91,17 +123,34 @@ RUN . /buildscripts/bh-set-envvars.sh \ # Build mongo-c-driver ARG MONGO_C_DRIVER_VERSION=1.24.4 -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-mongo-c-driver,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && mkdir mongo-c-driver \ && wget -q https://github.com/mongodb/mongo-c-driver/releases/download/${MONGO_C_DRIVER_VERSION}/mongo-c-driver-${MONGO_C_DRIVER_VERSION}.tar.gz -O - \ | tar xz -C mongo-c-driver --strip-components=1 \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/mongo-c-driver/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd mongo-c-driver \ && mkdir build_cmake \ && cd build_cmake \ - && cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_TESTS=NO -DCMAKE_BUILD_TYPE=Release \ - && make -j$(nproc) \ - && make install DESTDIR="/build_thirdparty" \ - && make install \ + && cmake .. -G Ninja $CCACHE_PARAM -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_TESTS=NO -DCMAKE_BUILD_TYPE=Release \ + && ninja \ + && DESTDIR="/build_thirdparty" ninja install \ + && ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/mongo-c-driver/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && cd ../.. \ && rm -rf mongo-c-driver \ && rm /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu/*.a \ @@ -110,17 +159,34 @@ RUN . /buildscripts/bh-set-envvars.sh \ # Build mongocxx ARG MONGOCXX_VERSION=3.8.1 -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-mongo-cxx-driver,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && mkdir mongocxx \ && wget -q https://github.com/mongodb/mongo-cxx-driver/archive/r${MONGOCXX_VERSION}.tar.gz -O - \ | tar xz -C mongocxx --strip-components=1 \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/mongo-cxx-driver/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd mongocxx \ && mkdir build_cmake \ && cd build_cmake \ - && cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBSONCXX_POLY_USE_BOOST=ON -DENABLE_TESTS=OFF -DMONGOCXX_ENABLE_SLOW_TESTS=NO -DCMAKE_BUILD_TYPE=Release -DBUILD_VERSION=${MONGOCXX_VERSION} \ - && make -j$(nproc) \ - && make install DESTDIR="/build_thirdparty" \ - && make install \ + && cmake .. -G Ninja $CCACHE_PARAM -DCMAKE_INSTALL_PREFIX=/usr -DBSONCXX_POLY_USE_BOOST=ON -DENABLE_TESTS=OFF -DMONGOCXX_ENABLE_SLOW_TESTS=NO -DCMAKE_BUILD_TYPE=Release -DBUILD_VERSION=${MONGOCXX_VERSION} \ + && ninja \ + && DESTDIR="/build_thirdparty" ninja install \ + && ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/mongo-cxx-driver/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && cd ../.. \ && rm -rf mongocxx \ && for i in /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu/*; do strip -s $i 2>/dev/null || /bin/true; done \ @@ -128,63 +194,83 @@ RUN . /buildscripts/bh-set-envvars.sh \ # Build tiledb ARG TILEDB_VERSION=2.23.0 -COPY ./tiledb-FindLZ4_EP.cmake.patch /buildscripts/tiledb-FindLZ4_EP.cmake.patch -COPY ./tiledb-FindOpenSSL_EP.cmake.patch /buildscripts/tiledb-FindOpenSSL_EP.cmake.patch -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y \ - libspdlog-dev${APT_ARCH_SUFFIX} libmagic-dev${APT_ARCH_SUFFIX} \ - && rm -rf /var/lib/apt/lists/* \ + libspdlog-dev${APT_ARCH_SUFFIX} libmagic-dev${APT_ARCH_SUFFIX} + +COPY ./tiledb-FindLZ4_EP.cmake.patch /buildscripts/tiledb-FindLZ4_EP.cmake.patch +COPY ./tiledb-FindOpenSSL_EP.cmake.patch /buildscripts/tiledb-FindOpenSSL_EP.cmake.patch +# Commit from TileDB 2.27. +COPY ./tiledb-cmake-ccache.patch /buildscripts/tiledb-cmake-ccache.patch +RUN --mount=type=cache,id=ubuntu-full-tiledb,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/tiledb/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + export CCACHE_PARAM="-DTILEDB_CCACHE=ON"; \ + ccache -M 100M; \ + fi \ && mkdir tiledb \ && wget -q https://github.com/TileDB-Inc/TileDB/archive/${TILEDB_VERSION}.tar.gz -O - \ | tar xz -C tiledb --strip-components=1 \ && cd tiledb \ && patch -p0 < /buildscripts/tiledb-FindLZ4_EP.cmake.patch \ && patch -p0 < /buildscripts/tiledb-FindOpenSSL_EP.cmake.patch \ + && patch -p1 < /buildscripts/tiledb-cmake-ccache.patch \ && mkdir build_cmake \ && cd build_cmake \ - && cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DTILEDB_WERROR=OFF -DTILEDB_SUPERBUILD=OFF -DTILEDB_TESTS=OFF -DCOMPILER_SUPPORTS_AVX2=FALSE -DOPENSSL_INCLUDE_DIR=/usr/include -DOPENSSL_CRYPTO_LIBRARY=/usr/lib/${GCC_ARCH}-linux-gnu/libcrypto.so -DOPENSSL_SSL_LIBRARY=/usr/lib/${GCC_ARCH}-linux-gnu/libssl.so \ - && make -j$(nproc) \ - && make -j$(nproc) install DESTDIR="/build_thirdparty" \ - && make -j$(nproc) install \ + && cmake .. -G Ninja $CCACHE_PARAM -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DTILEDB_WERROR=OFF -DTILEDB_SUPERBUILD=OFF -DTILEDB_TESTS=OFF -DCOMPILER_SUPPORTS_AVX2=FALSE -DOPENSSL_INCLUDE_DIR=/usr/include -DOPENSSL_CRYPTO_LIBRARY=/usr/lib/${GCC_ARCH}-linux-gnu/libcrypto.so -DOPENSSL_SSL_LIBRARY=/usr/lib/${GCC_ARCH}-linux-gnu/libssl.so \ + && ninja \ + && DESTDIR="/build_thirdparty" ninja install \ + && ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/tiledb/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && cd ../.. \ && rm -rf tiledb \ && for i in /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu/*; do strip -s $i 2>/dev/null || /bin/true; done \ && for i in /build_thirdparty/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done -# Build openjpeg -ARG OPENJPEG_VERSION= -RUN . /buildscripts/bh-set-envvars.sh \ - && if test "${OPENJPEG_VERSION}" != ""; then ( \ - wget -q https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \ - && tar xzf v${OPENJPEG_VERSION}.tar.gz \ - && rm -f v${OPENJPEG_VERSION}.tar.gz \ - && cd openjpeg-${OPENJPEG_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - && make -j$(nproc) \ - && make install \ - && mkdir -p /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu \ - && rm -f /usr/lib/${GCC_ARCH}-linux-gnu/libopenjp2.so* \ - && mv /usr/lib/libopenjp2.so* /usr/lib/${GCC_ARCH}-linux-gnu \ - && cp -P /usr/lib/${GCC_ARCH}-linux-gnu/libopenjp2.so* /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu \ - && for i in /build_thirdparty/usr/lib/${GCC_ARCH}-linux-gnu/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && cd .. \ - && rm -rf openjpeg-${OPENJPEG_VERSION} \ - ); fi - # Build libOpenDRIVE ARG OPENDRIVE_VERSION=0.6.0-gdal -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-libopendrive,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && if test "${OPENDRIVE_VERSION}" != ""; then ( \ wget -q https://github.com/DLR-TS/libOpenDRIVE/archive/refs/tags/${OPENDRIVE_VERSION}.tar.gz \ && tar xzf ${OPENDRIVE_VERSION}.tar.gz \ && rm -f ${OPENDRIVE_VERSION}.tar.gz \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/libopendrive/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd libOpenDRIVE-${OPENDRIVE_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ + && cmake . -G Ninja $CCACHE_PARAM -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/ \ - && make -j$(nproc) \ - && make install \ + && ninja \ + && ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/libopendrive/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && mkdir -p /build_thirdparty/usr/lib \ && cp -P /usr/lib/libOpenDrive*.so* /build_thirdparty/usr/lib \ && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ @@ -208,20 +294,39 @@ RUN . /buildscripts/bh-set-envvars.sh \ ) ; fi # Build libqb3 -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-libqb3,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && git clone https://github.com/lucianpls/QB3.git \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/libqb3/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd QB3/QB3lib \ && mkdir build \ && cd build \ - && cmake .. ${CMAKE_EXTRA_ARGS} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \ - && make -j$(nproc) \ - && make -j$(nproc) install \ - && make install DESTDIR="/build_thirdparty" \ + && cmake .. -G Ninja $CCACHE_PARAM ${CMAKE_EXTRA_ARGS} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \ + && ninja \ + && ninja install \ + && DESTDIR="/build_thirdparty" ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/libqb3/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && cd ../../.. \ && rm -rf QB3 ARG WITH_PDFIUM=yes -RUN if echo "$WITH_PDFIUM" | grep -Eiq "^(y(es)?|1|true)$" ; then ( \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + if echo "$WITH_PDFIUM" | grep -Eiq "^(y(es)?|1|true)$" ; then ( \ wget -q https://github.com/rouault/pdfium_build_gdal_3_10/releases/download/pdfium_6677_v1/install-ubuntu2004-rev6677.tar.gz \ && tar -xzf install-ubuntu2004-rev6677.tar.gz \ && chown -R root:root install \ @@ -230,35 +335,55 @@ RUN if echo "$WITH_PDFIUM" | grep -Eiq "^(y(es)?|1|true)$" ; then ( \ && rm -rf install-ubuntu2004-rev6677.tar.gz install \ && apt-get update -y \ && apt-get install -y --fix-missing --no-install-recommends liblcms2-dev${APT_ARCH_SUFFIX} \ - && rm -rf /var/lib/apt/lists/* \ ) ; fi # Build libjxl -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ - && apt-get install -y --fix-missing --no-install-recommends libgflags-dev${APT_ARCH_SUFFIX} \ + && apt-get install -y --fix-missing --no-install-recommends libgflags-dev${APT_ARCH_SUFFIX} +RUN --mount=type=cache,id=ubuntu-full-libjxl,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && git clone https://github.com/libjxl/libjxl.git --recursive \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Downloading cache..."; \ + rsync -ra "${RSYNC_REMOTE}/libjxl/${GCC_ARCH}/" "$HOME/.cache/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -M 100M; \ + fi \ && cd libjxl \ && mkdir build \ && cd build \ - && cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DJPEGXL_ENABLE_JPEGLI_LIBJPEG=OFF -DBUILD_TESTING=OFF -DJPEGXL_ENABLE_TOOLS=OFF -DJPEGXL_ENABLE_BENCHMARK=OFF .. \ - && make -j$(nproc) \ - && make -j$(nproc) install \ - && make install DESTDIR="/build_thirdparty" \ + && cmake -G Ninja $CCACHE_PARAM -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DJPEGXL_ENABLE_JPEGLI_LIBJPEG=OFF -DBUILD_TESTING=OFF -DJPEGXL_ENABLE_TOOLS=OFF -DJPEGXL_ENABLE_BENCHMARK=OFF .. \ + && ninja \ + && ninja install \ + && DESTDIR="/build_thirdparty" ninja install \ + && if [ -n "${RSYNC_REMOTE:-}" ]; then \ + echo "Uploading cache..."; \ + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/libjxl/${GCC_ARCH}/"; \ + echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ + fi \ && rm -f /lib/${GCC_ARCH}-linux-gnu/libjxl*.a \ && rm -f /build_thirdparty/lib/${GCC_ARCH}-linux-gnu/libjxl*.a \ && cd ../.. \ - && rm -rf libjxl \ - && rm -rf /var/lib/apt/lists/* + && rm -rf libjxl # Install Arrow C++ ARG ARROW_VERSION=16.1.0-1 # ARROW_SOVERSION to be updated in the "Build final image" section too ARG ARROW_SOVERSION=1600 -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V ca-certificates lsb-release wget \ - && wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ && apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libarrow${ARROW_SOVERSION}${APT_ARCH_SUFFIX} \ @@ -268,13 +393,25 @@ RUN . /buildscripts/bh-set-envvars.sh \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libparquet-dev${APT_ARCH_SUFFIX}=${ARROW_VERSION} \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libarrow-acero-dev${APT_ARCH_SUFFIX}=${ARROW_VERSION} \ && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libarrow-dataset-dev${APT_ARCH_SUFFIX}=${ARROW_VERSION} \ - && rm -rf /var/lib/apt/lists/* \ && rm apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb -RUN apt-get update -y \ - && apt-get install -y --fix-missing --no-install-recommends rsync ccache \ - && rm -rf /var/lib/apt/lists/* -ARG RSYNC_REMOTE +# Manually install ADBC packages from Ubuntu 22.04 as there are no 24.04 packages at time of writing. +RUN . /buildscripts/bh-set-envvars.sh \ + && if test "${GCC_ARCH}" = "x86_64"; then \ + curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake-dev_14-1_amd64.deb \ + && rm -f libadbc*.deb; \ + fi ARG WITH_DEBUG_SYMBOLS=no @@ -288,14 +425,16 @@ COPY ./bh-proj.sh /buildscripts/bh-proj.sh # We want 2 separate steps for incremental builds where grids are refreshed # only when the content of cdn.proj.org has changed, independently if PROJ master # itself has changed. -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-proj,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && DESTDIR=/build_tmp_proj /buildscripts/bh-proj.sh \ && LD_LIBRARY_PATH=/build_tmp_proj/usr/local/lib /build_tmp_proj/usr/local/bin/projsync --target-dir /tmp/proj_grids --all \ && rm -rf /build_tmp_proj # Build PROJ ARG PROJ_VERSION=master -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-proj,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && /buildscripts/bh-proj.sh # Build GDAL @@ -305,29 +444,31 @@ ARG GDAL_BUILD_IS_RELEASE ARG GDAL_REPOSITORY=OSGeo/gdal COPY ./bh-gdal.sh /buildscripts/bh-gdal.sh -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-full-gdal,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && /buildscripts/bh-gdal.sh # Build final image -FROM $TARGET_BASE_IMAGE as runner +FROM $TARGET_BASE_IMAGE AS runner USER root RUN date ARG JAVA_VERSION=17 ARG ARROW_SOVERSION=1600 -# Update distro -RUN apt-get update -y && apt-get upgrade -y \ - && rm -rf /var/lib/apt/lists/* - ARG TARGET_ARCH= -RUN apt-get update \ -# PROJ dependencies - && DEBIAN_FRONTEND=noninteractive apt-get install -y \ +# Update distro +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + export DEBIAN_FRONTEND=noninteractive \ + && apt-get update -y \ + && apt-get upgrade -y \ + # PROJ dependencies + && apt-get install -y \ libsqlite3-0 libtiff6 libcurl4 \ wget curl unzip ca-certificates \ -# GDAL dependencies - && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + # GDAL dependencies + && apt-get install -y \ libopenjp2-7 libcairo2 python3-numpy \ libpng16-16 libjpeg-turbo8 libgif7 liblzma5 libgeos3.12.1 libgeos-c1v5 \ libxml2 libexpat1 \ @@ -348,18 +489,42 @@ RUN apt-get update \ # pil for antialias option of gdal2tiles python3-pil \ # Install JRE with --no-install-recommends, otherwise it draws default-jre, which draws systemd, which fails to install when running the arm64v8/ubuntu:24.04 image on a 64bit host - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openjdk-"$JAVA_VERSION"-jre \ + && apt-get install -y --no-install-recommends openjdk-"$JAVA_VERSION"-jre \ # Worksround OGDI packaging bug for Ubuntu 24.04 && ln -s /usr/lib/$(uname -p)-linux-gnu/ogdi/4.1/libvrf.so /usr/lib/$(uname -p)-linux-gnu \ # Install Arrow C++ - && DEBIAN_FRONTEND=noninteractive apt-get install -y -V ca-certificates lsb-release wget \ - && wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y -V ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ + && apt-get install -y -V ca-certificates lsb-release wget \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ + && apt-get install -y -V ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \ && apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libarrow${ARROW_SOVERSION} \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libparquet${ARROW_SOVERSION} \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y -V libarrow-dataset${ARROW_SOVERSION} \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y -V libarrow${ARROW_SOVERSION} \ + && apt-get install -y -V libparquet${ARROW_SOVERSION} \ + && apt-get install -y -V libarrow-dataset${ARROW_SOVERSION} + +# Manually install ADBC packages from Ubuntu 22.04 as there are no 24.04 packages at time of writing. +RUN if test "$(uname -p)" = "x86_64"; then \ + curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-manager-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake102_14-1_amd64.deb \ + && curl -LO -fsS https://apache.jfrog.io/artifactory/arrow/ubuntu/pool/jammy/main/a/apache-arrow-adbc/libadbc-driver-snowflake-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-manager-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-sqlite-dev_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake102_14-1_amd64.deb \ + && dpkg -i libadbc-driver-snowflake-dev_14-1_amd64.deb \ + && rm -f libadbc*.deb; \ + fi + +# Install libduckdb +RUN if test "$(uname -p)" = "x86_64"; then \ + curl -LO -fsS https://github.com/duckdb/duckdb/releases/download/v1.1.3/libduckdb-linux-amd64.zip \ + && unzip libduckdb-linux-amd64.zip libduckdb.so \ + && mv libduckdb.so /usr/lib/x86_64-linux-gnu \ + && rm -f libduckdb-linux-amd64.zip; \ + fi # Attempt to order layers starting with less frequently varying ones @@ -380,3 +545,8 @@ COPY --from=builder /build_gdal_python/usr/ /usr/ COPY --from=builder /build_gdal_version_changing/usr/ /usr/ RUN ldconfig + +# Install duckdb_spatial +RUN if test "$(uname -p)" = "x86_64"; then \ + ogrinfo ADBC::memory: -oo ADBC_DRIVER=duckdb -oo PRELUDE_STATEMENTS="INSTALL spatial"; \ + fi diff --git a/docker/ubuntu-full/bh-gdal.sh b/docker/ubuntu-full/bh-gdal.sh index 4524d01ad4f3..b4a7659463c6 100755 --- a/docker/ubuntu-full/bh-gdal.sh +++ b/docker/ubuntu-full/bh-gdal.sh @@ -23,9 +23,10 @@ wget -q "https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz" \ if test "${RSYNC_REMOTE:-}" != ""; then echo "Downloading cache..." - rsync -ra "${RSYNC_REMOTE}/gdal/${GCC_ARCH}/" "$HOME/" + rsync -ra "${RSYNC_REMOTE}/gdal/${GCC_ARCH}/" "$HOME/.cache/" echo "Finished" - + fi + if [ -n "${WITH_CCACHE:-}" ]; then # Little trick to avoid issues with Python bindings printf "#!/bin/sh\nccache %s-linux-gnu-gcc \$*" "${GCC_ARCH}" > ccache_gcc.sh chmod +x ccache_gcc.sh @@ -45,7 +46,9 @@ wget -q "https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz" \ cd build # GDAL_USE_TIFF_INTERNAL=ON to use JXL export GDAL_CMAKE_EXTRA_OPTS="" - if test "${GCC_ARCH}" != "x86_64"; then + if test "${GCC_ARCH}" = "x86_64"; then + export GDAL_CMAKE_EXTRA_OPTS="${GDAL_CMAKE_EXTRA_OPTS} -DENABLE_IPO=ON" + else export GDAL_CMAKE_EXTRA_OPTS="${GDAL_CMAKE_EXTRA_OPTS} -DPDFIUM_INCLUDE_DIR=" fi export JAVA_ARCH="" @@ -64,6 +67,7 @@ wget -q "https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz" \ fi echo "${GDAL_CMAKE_EXTRA_OPTS}" cmake .. \ + -G Ninja \ -DCMAKE_INSTALL_PREFIX=/usr \ -DGDAL_FIND_PACKAGE_PROJ_MODE=MODULE \ -DBUILD_TESTING=OFF \ @@ -76,19 +80,18 @@ wget -q "https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz" \ -DOpenDrive_DIR=/usr/lib/ \ -DOGR_ENABLE_DRIVER_XODR_PLUGIN=TRUE \ - make "-j$(nproc)" - make install DESTDIR="/build" + ninja + DESTDIR="/build" ninja install cd .. if [ -n "${RSYNC_REMOTE:-}" ]; then - ccache -s - echo "Uploading cache..." - rsync -ra --delete "$HOME/.cache" "${RSYNC_REMOTE}/gdal/${GCC_ARCH}/" + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/gdal/${GCC_ARCH}/" echo "Finished" - - rm -rf "$HOME/.cache" + fi + if [ -n "${WITH_CCACHE:-}" ]; then + ccache -s unset CC unset CXX fi diff --git a/docker/ubuntu-full/bh-proj.sh b/docker/ubuntu-full/bh-proj.sh index 410958247947..42ca2ea1c919 100755 --- a/docker/ubuntu-full/bh-proj.sh +++ b/docker/ubuntu-full/bh-proj.sh @@ -18,15 +18,17 @@ wget -q "https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz" \ ( cd proj + export PROJ_DB_CACHE_PARAM="" if [ -n "${RSYNC_REMOTE:-}" ]; then echo "Downloading cache..." - rsync -ra "${RSYNC_REMOTE}/proj/${GCC_ARCH}/" "$HOME/" + rsync -ra "${RSYNC_REMOTE}/proj/${GCC_ARCH}/" "$HOME/.cache/" echo "Finished" - + fi + if [ -n "${WITH_CCACHE:-}" ]; then export CC="ccache ${GCC_ARCH}-linux-gnu-gcc" export CXX="ccache ${GCC_ARCH}-linux-gnu-g++" - export PROJ_DB_CACHE_DIR="$HOME/.cache" + export PROJ_DB_CACHE_PARAM="-DPROJ_DB_CACHE_DIR=$HOME/.cache" ccache -M 100M fi @@ -35,21 +37,22 @@ wget -q "https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz" \ export CXXFLAGS="-DPROJ_RENAME_SYMBOLS -DPROJ_INTERNAL_CPP_NAMESPACE -O2 -g" cmake . \ + -G Ninja \ -DBUILD_SHARED_LIBS=ON \ -DCMAKE_INSTALL_PREFIX=${PROJ_INSTALL_PREFIX:-/usr/local} \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + $PROJ_DB_CACHE_PARAM - make "-j$(nproc)" - make install DESTDIR="${DESTDIR}" + ninja + DESTDIR="${DESTDIR}" ninja install if [ -n "${RSYNC_REMOTE:-}" ]; then - ccache -s - echo "Uploading cache..." - rsync -ra --delete "$HOME/.cache" "${RSYNC_REMOTE}/proj/${GCC_ARCH}/" + rsync -ra --delete "$HOME/.cache/" "${RSYNC_REMOTE}/proj/${GCC_ARCH}/" echo "Finished" - - rm -rf "$HOME/.cache" + fi + if [ -n "${WITH_CCACHE:-}" ]; then + ccache -s unset CC unset CXX fi @@ -97,9 +100,6 @@ else done; fi -apt-get update -y -DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y patchelf -rm -rf /var/lib/apt/lists/* patchelf --set-soname libinternalproj.so.${PROJ_SO_FIRST} ${DESTDIR}${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} for i in "${DESTDIR}${PROJ_INSTALL_PREFIX}/bin"/*; do patchelf --replace-needed libproj.so.${PROJ_SO_FIRST} libinternalproj.so.${PROJ_SO_FIRST} $i; diff --git a/docker/ubuntu-full/bh-set-envvars.sh b/docker/ubuntu-full/bh-set-envvars.sh index e64393454f26..d8633df9511f 100644 --- a/docker/ubuntu-full/bh-set-envvars.sh +++ b/docker/ubuntu-full/bh-set-envvars.sh @@ -20,3 +20,10 @@ else export GCC_ARCH export CMAKE_EXTRA_ARGS="" fi + +if [ -n "${WITH_CCACHE:-}" ]; then + CCACHE_PARAM="-DCMAKE_C_COMPILER_LAUNCHER=ccache" + export CCACHE_PARAM="$CCACHE_PARAM -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" +else + export CCACHE_PARAM="" +fi diff --git a/docker/ubuntu-full/tiledb-cmake-ccache.patch b/docker/ubuntu-full/tiledb-cmake-ccache.patch new file mode 100644 index 000000000000..76e888e27569 --- /dev/null +++ b/docker/ubuntu-full/tiledb-cmake-ccache.patch @@ -0,0 +1,50 @@ +commit 16c3aa25b9e9401b91cd70f2118c7a86f12140b4 +Author: Theodore Tsirpanis +Date: Thu Oct 10 12:43:05 2024 +0300 + + Re-enable `TILEDB_CCACHE` support. + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index fef5de5ce..d84fb3d6b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,6 +105,12 @@ else() + set(CMAKE_CXX_EXTENSIONS OFF) + endif() + ++if (TILEDB_CCACHE) ++ include(FindCcache) ++ set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) ++ set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE}) ++endif() ++ + # Set -fvisibility=hidden (or equivalent) flags by default. + set(CMAKE_C_VISIBILITY_PRESET hidden) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) +diff --git a/cmake/Modules/FindCcache.cmake b/cmake/Modules/FindCcache.cmake +index 06be83ea3..c981e9dcf 100644 +--- a/cmake/Modules/FindCcache.cmake ++++ b/cmake/Modules/FindCcache.cmake +@@ -1,16 +1,9 @@ + ## cf https://stackoverflow.com/questions/1815688/how-to-use-ccache-with-cmake + ## leading to https://invent.kde.org/kde/konsole/merge_requests/26/diffs +-find_program(CCACHE_FOUND NAMES "sccache" "ccache") +-set(CCACHE_SUPPORT ON CACHE BOOL "Enable ccache support") +-if (CCACHE_FOUND AND CCACHE_SUPPORT) +- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" # GNU is GNU GCC +- OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +- # without this compiler messages in `make` backend would be uncolored +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto") +- endif() +- set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_FOUND}) +- set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_FOUND}) +- message(STATUS "Found ccache: ${CCACHE_FOUND}") +-else() +- message(FATAL_ERROR "Unable to find ccache") ++find_program(CCACHE REQUIRED NAMES "sccache" "ccache") ++ ++if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" # GNU is GNU GCC ++ OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") ++ # without this compiler messages in `make` backend would be uncolored ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto") + endif() diff --git a/docker/ubuntu-small/Dockerfile b/docker/ubuntu-small/Dockerfile index 7a31cded59cb..65cf4fd17b3a 100644 --- a/docker/ubuntu-small/Dockerfile +++ b/docker/ubuntu-small/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ## # osgeo/gdal:ubuntu-small @@ -9,16 +11,23 @@ ARG PROJ_INSTALL_PREFIX=/usr/local ARG BASE_IMAGE=ubuntu:24.04 ARG TARGET_BASE_IMAGE=ubuntu:24.04 -FROM $BASE_IMAGE as builder +FROM $BASE_IMAGE AS builder # Derived from osgeo/proj by Howard Butler LABEL maintainer="Even Rouault " +ENV HOME="/root" + ARG TARGET_ARCH= RUN echo ${TARGET_ARCH} COPY ./bh-set-envvars.sh /buildscripts/bh-set-envvars.sh -RUN . /buildscripts/bh-set-envvars.sh \ +RUN rm -f /etc/apt/apt.conf.d/docker-clean \ + && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \ + && echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retries +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && if test "${TARGET_ARCH}" != ""; then \ rm -f /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources \ && echo "deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe" >> /etc/apt/sources.list \ @@ -32,23 +41,27 @@ RUN . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y g++-13-${GCC_ARCH}-linux-gnu \ && ln -s ${GCC_ARCH}-linux-gnu-gcc-13 /usr/bin/${GCC_ARCH}-linux-gnu-gcc \ - && ln -s ${GCC_ARCH}-linux-gnu-g++-13 /usr/bin/${GCC_ARCH}-linux-gnu-g++ \ - && rm -rf /var/lib/apt/lists/*; \ + && ln -s ${GCC_ARCH}-linux-gnu-g++-13 /usr/bin/${GCC_ARCH}-linux-gnu-g++; \ fi # Setup build env for PROJ USER root -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \ - build-essential ca-certificates \ - git make cmake wget unzip libtool automake \ + build-essential ca-certificates ccache \ + git make ninja-build cmake wget unzip libtool automake \ zlib1g-dev${APT_ARCH_SUFFIX} libsqlite3-dev${APT_ARCH_SUFFIX} pkg-config sqlite3 libcurl4-openssl-dev${APT_ARCH_SUFFIX} \ libtiff-dev${APT_ARCH_SUFFIX} \ - && rm -rf /var/lib/apt/lists/* + patchelf \ + rsync # Setup build env for GDAL -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /buildscripts/bh-set-envvars.sh \ && apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing --no-install-recommends \ python3-dev${APT_ARCH_SUFFIX} python3-numpy${APT_ARCH_SUFFIX} python3-setuptools${APT_ARCH_SUFFIX} \ @@ -59,71 +72,56 @@ RUN . /buildscripts/bh-set-envvars.sh \ libzstd-dev${APT_ARCH_SUFFIX} bash zip curl \ libpq-dev${APT_ARCH_SUFFIX} libssl-dev${APT_ARCH_SUFFIX} libopenjp2-7-dev${APT_ARCH_SUFFIX} \ libspatialite-dev${APT_ARCH_SUFFIX} \ - autoconf automake sqlite3 bash-completion swig \ - && rm -rf /var/lib/apt/lists/* - -# Build openjpeg -ARG OPENJPEG_VERSION= -RUN . /buildscripts/bh-set-envvars.sh \ - && if test "${OPENJPEG_VERSION}" != ""; then ( \ - wget -q https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \ - && tar xzf v${OPENJPEG_VERSION}.tar.gz \ - && rm -f v${OPENJPEG_VERSION}.tar.gz \ - && cd openjpeg-${OPENJPEG_VERSION} \ - && cmake . -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - && make -j$(nproc) \ - && make install \ - && mkdir -p /build_thirdparty/usr/lib \ - && cp -P /usr/lib/libopenjp2*.so* /build_thirdparty/usr/lib \ - && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ - && cd .. \ - && rm -rf openjpeg-${OPENJPEG_VERSION} \ - ); fi + autoconf automake sqlite3 bash-completion swig ARG PROJ_INSTALL_PREFIX ARG PROJ_DATUMGRID_LATEST_LAST_MODIFIED RUN \ mkdir -p /build_projgrids/${PROJ_INSTALL_PREFIX}/share/proj \ - && curl -LOs http://download.osgeo.org/proj/proj-datumgrid-latest.zip \ + && curl -LO -fsS http://download.osgeo.org/proj/proj-datumgrid-latest.zip \ && unzip -q -j -u -o proj-datumgrid-latest.zip -d /build_projgrids/${PROJ_INSTALL_PREFIX}/share/proj \ && rm -f *.zip -RUN apt-get update -y \ - && apt-get install -y --fix-missing --no-install-recommends rsync ccache \ - && rm -rf /var/lib/apt/lists/* ARG RSYNC_REMOTE +ARG WITH_CCACHE # Build PROJ ARG PROJ_VERSION=master -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-small-proj,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && mkdir proj \ && wget -q https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz -O - \ | tar xz -C proj --strip-components=1 \ + && export PROJ_DB_CACHE_PARAM="" \ && cd proj \ && if test "${RSYNC_REMOTE:-}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/proj/${GCC_ARCH}/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/proj/${GCC_ARCH}/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ export CC="ccache ${GCC_ARCH}-linux-gnu-gcc"; \ export CXX="ccache ${GCC_ARCH}-linux-gnu-g++"; \ - export PROJ_DB_CACHE_DIR="$HOME/.ccache"; \ + export PROJ_DB_CACHE_PARAM="-DPROJ_DB_CACHE_DIR=$HOME/.cache"; \ ccache -M 100M; \ fi \ && CFLAGS='-DPROJ_RENAME_SYMBOLS -O2' CXXFLAGS='-DPROJ_RENAME_SYMBOLS -DPROJ_INTERNAL_CPP_NAMESPACE -O2' \ cmake . \ + -G Ninja \ -DBUILD_SHARED_LIBS=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=${PROJ_INSTALL_PREFIX} \ -DBUILD_TESTING=OFF \ - && make -j$(nproc) \ - && make install DESTDIR="/build" \ + $PROJ_DB_CACHE_PARAM \ + && ninja \ + && DESTDIR="/build" ninja install \ && if test "${RSYNC_REMOTE:-}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/proj/${GCC_ARCH}/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/proj/${GCC_ARCH}/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -137,9 +135,6 @@ RUN . /buildscripts/bh-set-envvars.sh \ && rm /build${PROJ_INSTALL_PREFIX}/lib/libproj.* \ && ${GCC_ARCH}-linux-gnu-strip -s /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} \ && for i in /build${PROJ_INSTALL_PREFIX}/bin/*; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done \ - && apt-get update -y \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y patchelf \ - && rm -rf /var/lib/apt/lists/* \ && patchelf --set-soname libinternalproj.so.${PROJ_SO_FIRST} /build${PROJ_INSTALL_PREFIX}/lib/libinternalproj.so.${PROJ_SO} \ && for i in /build${PROJ_INSTALL_PREFIX}/bin/*; do patchelf --replace-needed libproj.so.${PROJ_SO_FIRST} libinternalproj.so.${PROJ_SO_FIRST} $i; done @@ -149,7 +144,8 @@ ARG GDAL_RELEASE_DATE ARG GDAL_BUILD_IS_RELEASE ARG GDAL_REPOSITORY=OSGeo/gdal -RUN . /buildscripts/bh-set-envvars.sh \ +RUN --mount=type=cache,id=ubuntu-small-gdal,target=$HOME/.cache \ + . /buildscripts/bh-set-envvars.sh \ && if test "${GDAL_VERSION}" = "master"; then \ export GDAL_VERSION=$(curl -Ls https://api.github.com/repos/${GDAL_REPOSITORY}/commits/HEAD -H "Accept: application/vnd.github.VERSION.sha"); \ export GDAL_RELEASE_DATE=$(date "+%Y%m%d"); \ @@ -157,14 +153,21 @@ RUN . /buildscripts/bh-set-envvars.sh \ && if test "x${GDAL_BUILD_IS_RELEASE:-}" = "x"; then \ export GDAL_SHA1SUM=${GDAL_VERSION}; \ fi \ + && if test "${GCC_ARCH}" = "x86_64"; then \ + export GDAL_CMAKE_EXTRA_OPTS="-DENABLE_IPO=ON"; \ + else \ + export GDAL_CMAKE_EXTRA_OPTS=""; \ + fi \ && mkdir gdal \ && wget -q https://github.com/${GDAL_REPOSITORY}/archive/${GDAL_VERSION}.tar.gz -O - \ | tar xz -C gdal --strip-components=1 \ && cd gdal \ && if test "${RSYNC_REMOTE:-}" != ""; then \ echo "Downloading cache..."; \ - rsync -ra ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/ $HOME/; \ + rsync -ra ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/ $HOME/.cache/; \ echo "Finished"; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ # Little trick to avoid issues with Python bindings printf "#!/bin/sh\nccache %s-linux-gnu-gcc \$*" "${GCC_ARCH}" > ccache_gcc.sh; \ chmod +x ccache_gcc.sh; \ @@ -179,22 +182,24 @@ RUN . /buildscripts/bh-set-envvars.sh \ # -Wno-psabi avoid 'note: parameter passing for argument of type 'std::pair' when C++17 is enabled changed to match C++14 in GCC 10.1' on arm64 && CFLAGS='-DPROJ_RENAME_SYMBOLS -O2' CXXFLAGS='-DPROJ_RENAME_SYMBOLS -DPROJ_INTERNAL_CPP_NAMESPACE -O2 -Wno-psabi' \ cmake .. \ + -G Ninja \ -DCMAKE_INSTALL_PREFIX=/usr \ -DGDAL_FIND_PACKAGE_PROJ_MODE=MODULE \ -DPROJ_INCLUDE_DIR="/build${PROJ_INSTALL_PREFIX-/usr/local}/include" \ -DPROJ_LIBRARY="/build${PROJ_INSTALL_PREFIX-/usr/local}/lib/libinternalproj.so" \ -DGDAL_USE_TIFF_INTERNAL=ON \ - -DGDAL_USE_GEOTIFF_INTERNAL=ON \ + -DGDAL_USE_GEOTIFF_INTERNAL=ON ${GDAL_CMAKE_EXTRA_OPTS} \ -DBUILD_TESTING=OFF \ - && make -j$(nproc) \ - && make install DESTDIR="/build" \ + && ninja \ + && DESTDIR="/build" ninja install \ && cd .. \ && if test "${RSYNC_REMOTE:-}" != ""; then \ - ccache -s; \ echo "Uploading cache..."; \ - rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/; \ + rsync -ra --delete $HOME/.cache/ ${RSYNC_REMOTE}/gdal/${GCC_ARCH}/; \ echo "Finished"; \ - rm -rf $HOME/.ccache; \ + fi \ + && if [ -n "${WITH_CCACHE:-}" ]; then \ + ccache -s; \ unset CC; \ unset CXX; \ fi \ @@ -213,25 +218,23 @@ RUN . /buildscripts/bh-set-envvars.sh \ && for i in /build_gdal_version_changing/usr/bin/*; do ${GCC_ARCH}-linux-gnu-strip -s $i 2>/dev/null || /bin/true; done # Build final image -FROM $TARGET_BASE_IMAGE as runner +FROM $TARGET_BASE_IMAGE AS runner USER root RUN date # Update distro -RUN apt-get update -y && apt-get upgrade -y \ - && rm -rf /var/lib/apt/lists/* - -RUN apt-get update \ -# PROJ dependencies - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + export DEBIAN_FRONTEND=noninteractive \ + && apt-get update -y \ + && apt-get upgrade -y \ + # PROJ dependencies + && apt-get install -y --no-install-recommends \ libsqlite3-0 libtiff6 libcurl4 \ curl unzip ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# GDAL dependencies -RUN apt-get update -y \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + # GDAL dependencies + && apt-get install -y --no-install-recommends \ python3-numpy libpython3.12 \ libjpeg-turbo8 libgeos3.12.1 libgeos-c1v5 \ libexpat1 \ @@ -241,12 +244,7 @@ RUN apt-get update -y \ libzstd1 bash libpq5 libssl3 libopenjp2-7 libspatialite8 \ # pil for antialias option of gdal2tiles python3-pil \ - && rm -rf /var/lib/apt/lists/* - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y \ - python-is-python3 \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y python-is-python3 # Order layers starting with less frequently varying ones # Only used for custom libopenjp2 diff --git a/docker/util.sh b/docker/util.sh index 42cefda20b66..7c604794c7f5 100755 --- a/docker/util.sh +++ b/docker/util.sh @@ -17,7 +17,7 @@ fi usage() { - echo "Usage: build.sh [--push] [--docker-repository repo] [--tag name] [--gdal tag|sha1|master] [--gdal-repository repo] [--proj tag|sha1|master] [--release]" + echo "Usage: build.sh [--push] [--docker-repository repo] [--tag name] [--gdal tag|sha1|master] [--gdal-repository repo] [--proj tag|sha1|master] [--release] [--docker-cache|--no-docker-cache] [--no-rsync-daemon]" # Non-documented: --test-python echo "" echo "--push: push image to docker repository (defaults to ghcr.io)" @@ -25,7 +25,9 @@ usage() echo "--gdal tag|sha1|master: GDAL version to use. Defaults to master" echo "--proj tag|sha1|master: PROJ version to use. Defaults to master" echo "--gdal-repository repo: github repository. Defaults to OSGeo/gdal" - echo "--release. Whether this is a release build. In which case --gdal tag must be used." + echo "--release: Whether this is a release build. In which case --gdal tag must be used." + echo "--docker-cache/--no-docker-cache: instruct Docker to build with/without using its cache. Defaults to no cache for release builds." + echo "--no-rsync-daemon: do not use the rsync daemon to save build cache in home directory." echo "--with-debug-symbols/--without-debug-symbols. Whether to include debug symbols. Only applies to ubuntu-full, default is to include for non-release builds." exit 1 } @@ -48,7 +50,7 @@ do shift ;; - docker-repository) + --docker-repository) shift DOCKER_REPO="$1" shift @@ -100,6 +102,20 @@ do shift ;; + --docker-cache) + DOCKER_CACHE_PARAM="" + shift + ;; + --no-docker-cache) + DOCKER_CACHE_PARAM="--no-cache" + shift + ;; + + --no-rsync-daemon) + NO_RSYNC_DAEMON=1 + shift + ;; + --without-debug-symbols) WITH_DEBUG_SYMBOLS=no shift @@ -126,13 +142,6 @@ if test "${DOCKER_BUILDKIT}" = "1" && test "${DOCKER_CLI_EXPERIMENTAL}" = "enabl DOCKER_BUILDX_ARGS=("--platform" "${ARCH_PLATFORMS}") fi -# Docker 23 uses BuildKit by default on Linux, but BuildKit prevents -# custom networks using docker build --network, so disable BuildKit for now. -# https://github.com/moby/buildkit/issues/978 -if test -z "${DOCKER_BUILDKIT}"; then - export DOCKER_BUILDKIT=0 -fi - if test "${RELEASE}" = "yes"; then if test "${GDAL_VERSION}" = ""; then echo "--gdal tag must be specified when --release is used." @@ -152,6 +161,7 @@ if test "${RELEASE}" = "yes"; then if test "${WITH_DEBUG_SYMBOLS}" = ""; then WITH_DEBUG_SYMBOLS=no fi + [ -v DOCKER_CACHE_PARAM ] || DOCKER_CACHE_PARAM="--no-cache" else if test "${TAG_NAME}" = ""; then TAG_NAME=latest @@ -159,6 +169,7 @@ else if test "${WITH_DEBUG_SYMBOLS}" = ""; then WITH_DEBUG_SYMBOLS=yes fi + [ -v DOCKER_CACHE_PARAM ] || DOCKER_CACHE_PARAM="" fi check_image() @@ -171,76 +182,6 @@ check_image() fi } -# No longer used -cleanup_rsync() -{ - rm -f "${RSYNC_DAEMON_TEMPFILE}" - if test "${RSYNC_PID}" != ""; then - kill "${RSYNC_PID}" || true - fi -} - -# No longer used -trap_error_exit() -{ - echo "Exit on error... clean up" - cleanup_rsync - exit 1 -} - -# No longer used -start_rsync_host() -{ - # If rsync is available then start it as a temporary daemon - if test "${USE_CACHE:-yes}" = "yes" -a -x "$(command -v rsync)"; then - - RSYNC_SERVER_IP=$(ip -4 -o addr show docker0 | awk '{print $4}' | cut -d "/" -f 1) - if test "${RSYNC_SERVER_IP}" = ""; then - exit 1 - fi - - RSYNC_DAEMON_TEMPFILE=$(mktemp) - - # Trap exit - trap "trap_error_exit" EXIT - - cat < "${RSYNC_DAEMON_TEMPFILE}" -[gdal-docker-cache] - path = $HOME/gdal-docker-cache - comment = GDAL Docker cache - hosts allow = ${RSYNC_SERVER_IP}/24 - use chroot = false - read only = false -EOF - RSYNC_PORT=23985 - while true; do - rsync --port=${RSYNC_PORT} --address="${RSYNC_SERVER_IP}" --config="${RSYNC_DAEMON_TEMPFILE}" --daemon --no-detach & - RSYNC_PID=$! - sleep 1 - kill -0 ${RSYNC_PID} 2>/dev/null && break - echo "Port ${RSYNC_PORT} is in use. Trying next one" - RSYNC_PORT=$((RSYNC_PORT+1)) - done - echo "rsync daemon forked as process ${RSYNC_PID} listening on port ${RSYNC_PORT}" - - RSYNC_REMOTE="rsync://${RSYNC_SERVER_IP}:${RSYNC_PORT}/gdal-docker-cache/${TARGET_IMAGE}" - mkdir -p "$HOME/gdal-docker-cache/${TARGET_IMAGE}/proj" - mkdir -p "$HOME/gdal-docker-cache/${TARGET_IMAGE}/gdal" - mkdir -p "$HOME/gdal-docker-cache/${TARGET_IMAGE}/spatialite" - else - RSYNC_REMOTE="" - fi -} - -# No longer used -stop_rsync_host() -{ - if test "${RSYNC_REMOTE}" != ""; then - cleanup_rsync - trap - EXIT - fi -} - build_cmd() { if test "${DOCKER_BUILDX}" = "buildx"; then @@ -270,17 +211,34 @@ echo "Using GDAL_REPOSITORY=${GDAL_REPOSITORY}" IMAGE_NAME="${TARGET_IMAGE}-${TAG_NAME}" REPO_IMAGE_NAME="${DOCKER_REPO}/${IMAGE_NAME}" -BUILDER_IMAGE_NAME="${DOCKER_REPO}/${IMAGE_NAME}_builder" + +BUILD_ARGS=( + "--build-arg" "PROJ_DATUMGRID_LATEST_LAST_MODIFIED=${PROJ_DATUMGRID_LATEST_LAST_MODIFIED}" \ + "--build-arg" "PROJ_VERSION=${PROJ_VERSION}" \ + "--build-arg" "GDAL_VERSION=${GDAL_VERSION}" \ + "--build-arg" "GDAL_REPOSITORY=${GDAL_REPOSITORY}" \ + "--build-arg" "WITH_DEBUG_SYMBOLS=${WITH_DEBUG_SYMBOLS}" \ +) +[ -z "${DOCKER_CACHE_PARAM}" ] || BUILD_ARGS+=("${DOCKER_CACHE_PARAM}") if test "${RELEASE}" = "yes"; then - BUILD_ARGS=( - "--build-arg" "PROJ_DATUMGRID_LATEST_LAST_MODIFIED=${PROJ_DATUMGRID_LATEST_LAST_MODIFIED}" \ - "--build-arg" "PROJ_VERSION=${PROJ_VERSION}" \ - "--build-arg" "GDAL_VERSION=${GDAL_VERSION}" \ - "--build-arg" "GDAL_REPOSITORY=${GDAL_REPOSITORY}" \ - "--build-arg" "GDAL_BUILD_IS_RELEASE=YES" \ - "--build-arg" "WITH_DEBUG_SYMBOLS=${WITH_DEBUG_SYMBOLS}" \ - ) + BUILD_ARGS+=("--build-arg" "GDAL_BUILD_IS_RELEASE=YES") + + if [ -z "${SOURCE_DATE_EPOCH}" ]; then + # Try to set SOURCE_DATE_EPOCH to the timestamp of the tar.gz for + # the release, so repeated builds give similar output. + # https://github.com/moby/buildkit/blob/master/docs/build-repro.md#source_date_epoch + # Will proceed without setting SOURCE_DATE_EPOCH when failing to get + # the timestamp, so "build.sh --gdal HEAD" works. + LAST_MODIFIED=$(curl -L -sI "https://github.com/OSGeo/gdal/releases/download/${GDAL_VERSION}/gdal-${GDAL_VERSION#v}.tar.gz" \ + | grep -i last-modified | awk -F: '{print $2}') + if [ -n "${LAST_MODIFIED}" ]; then + MODIFIED_SINCE_EPOCH=$(date -d "${LAST_MODIFIED}" +%s) + if [ -n "${MODIFIED_SINCE_EPOCH}" ]; then + export SOURCE_DATE_EPOCH="${MODIFIED_SINCE_EPOCH}" + fi + fi + fi if test "${BASE_IMAGE}" != ""; then BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${BASE_IMAGE}") @@ -302,7 +260,6 @@ if test "${RELEASE}" = "yes"; then if test "${DOCKER_BUILDX}" = "buildx" -a "${PUSH_GDAL_DOCKER_IMAGE}" = "yes"; then docker $(build_cmd) "${BUILD_ARGS[@]}" "${LABEL_ARGS[@]}" -t "${REPO_IMAGE_NAME}" --push "${SCRIPT_DIR}" else - docker $(build_cmd) "${BUILD_ARGS[@]}" "${LABEL_ARGS[@]}" --target builder -t "${BUILDER_IMAGE_NAME}" "${SCRIPT_DIR}" docker $(build_cmd) "${BUILD_ARGS[@]}" "${LABEL_ARGS[@]}" -t "${REPO_IMAGE_NAME}" "${SCRIPT_DIR}" if test "${DOCKER_BUILDX}" != "buildx"; then @@ -315,6 +272,8 @@ if test "${RELEASE}" = "yes"; then fi else + BUILD_ARGS+=("--build-arg" "BUILDKIT_INLINE_CACHE=1") + BUILD_ARGS+=("--build-arg" "WITH_CCACHE=1") IMAGE_NAME_WITH_ARCH="${REPO_IMAGE_NAME}" if test "${IMAGE_NAME}" = "osgeo/gdal:ubuntu-full-latest" \ @@ -324,33 +283,36 @@ else if test "${DOCKER_BUILDX}" != "buildx"; then ARCH_PLATFORM_ARCH=$(echo ${ARCH_PLATFORMS} | sed "s/linux\///") IMAGE_NAME_WITH_ARCH="${REPO_IMAGE_NAME}-${ARCH_PLATFORM_ARCH}" - BUILDER_IMAGE_NAME="${BUILDER_IMAGE_NAME}_${ARCH_PLATFORM_ARCH}" fi fi - OLD_BUILDER_ID=$(docker image ls "${BUILDER_IMAGE_NAME}" -q) OLD_IMAGE_ID=$(docker image ls "${IMAGE_NAME_WITH_ARCH}" -q) if test "${GDAL_RELEASE_DATE}" = ""; then GDAL_RELEASE_DATE=$(date "+%Y%m%d") fi echo "Using GDAL_RELEASE_DATE=${GDAL_RELEASE_DATE}" - - RSYNC_DAEMON_CONTAINER=gdal_rsync_daemon - BUILD_NETWORK=docker_build_gdal - HOST_CACHE_DIR="$HOME/gdal-docker-cache" - - mkdir -p "${HOST_CACHE_DIR}/${TARGET_IMAGE}/proj/x86_64" - mkdir -p "${HOST_CACHE_DIR}/${TARGET_IMAGE}/proj/aarch64" - mkdir -p "${HOST_CACHE_DIR}/${TARGET_IMAGE}/gdal/x86_64" - mkdir -p "${HOST_CACHE_DIR}/${TARGET_IMAGE}/gdal/aarch64" - mkdir -p "${HOST_CACHE_DIR}/${TARGET_IMAGE}/spatialite" - - # Start a Docker container that has a rsync daemon, mounting HOST_CACHE_DIR - if ! docker ps | grep "${RSYNC_DAEMON_CONTAINER}"; then - RSYNC_DAEMON_IMAGE=osgeo/gdal:gdal_rsync_daemon - docker rmi "${RSYNC_DAEMON_IMAGE}" 2>/dev/null || true - docker $(build_cmd) -t "${RSYNC_DAEMON_IMAGE}" - </dev/null || true + docker $(build_cmd) -t "${RSYNC_DAEMON_IMAGE}" - < * Copyright (c) 2014, Kyle Shannon * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // We need cpl_port as first include to avoid VSIStatBufL being not diff --git a/frmts/aaigrid/aaigriddataset.h b/frmts/aaigrid/aaigriddataset.h index fcdb8a7058bd..0cbf4dfdc2fa 100644 --- a/frmts/aaigrid/aaigriddataset.h +++ b/frmts/aaigrid/aaigriddataset.h @@ -10,23 +10,7 @@ * Copyright (c) 2007-2012, Even Rouault * Copyright (c) 2014, Kyle Shannon * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_FRMTS_AAIGRID_AAIGRIDDATASET_H_INCLUDED diff --git a/frmts/adrg/adrgdataset.cpp b/frmts/adrg/adrgdataset.cpp index b64abaa9bb11..ee460adf0653 100644 --- a/frmts/adrg/adrgdataset.cpp +++ b/frmts/adrg/adrgdataset.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/frmts/adrg/srpdataset.cpp b/frmts/adrg/srpdataset.cpp index 018da7fb2320..c35346a7ce67 100644 --- a/frmts/adrg/srpdataset.cpp +++ b/frmts/adrg/srpdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2009-2013, Even Rouault * Copyright (c) 2009, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/frmts/aigrid/aigdataset.cpp b/frmts/aigrid/aigdataset.cpp index 4c04adc7a8d2..fc363c34d766 100644 --- a/frmts/aigrid/aigdataset.cpp +++ b/frmts/aigrid/aigdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "aigrid.h" diff --git a/frmts/aigrid/aigopen.c b/frmts/aigrid/aigopen.c index 72bcc813b793..c3db7ba6dcf5 100644 --- a/frmts/aigrid/aigopen.c +++ b/frmts/aigrid/aigopen.c @@ -9,23 +9,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2009-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "aigrid.h" diff --git a/frmts/aigrid/aigrid.h b/frmts/aigrid/aigrid.h index 731bff6226b5..1ef9da9792c9 100644 --- a/frmts/aigrid/aigrid.h +++ b/frmts/aigrid/aigrid.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef AIGRID_H_INCLUDED diff --git a/frmts/aigrid/aitest.c b/frmts/aigrid/aitest.c index 5db09f6253cd..d14fe567205a 100644 --- a/frmts/aigrid/aitest.c +++ b/frmts/aigrid/aitest.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #include "aigrid.h" diff --git a/frmts/aigrid/gridlib.c b/frmts/aigrid/gridlib.c index 9118e96fbc35..f35bfcb4a6d0 100644 --- a/frmts/aigrid/gridlib.c +++ b/frmts/aigrid/gridlib.c @@ -9,23 +9,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2007-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "aigrid.h" diff --git a/frmts/airsar/airsardataset.cpp b/frmts/airsar/airsardataset.cpp index 248564afc3da..8043cf428638 100644 --- a/frmts/airsar/airsardataset.cpp +++ b/frmts/airsar/airsardataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2004, Frank Warmerdam * Copyright (c) 2007-2009, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/frmts/avif/avifdataset.cpp b/frmts/avif/avifdataset.cpp index bb94754d211c..ff0dca786395 100644 --- a/frmts/avif/avifdataset.cpp +++ b/frmts/avif/avifdataset.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2024, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_pam.h" @@ -603,7 +587,7 @@ GDALDataset *GDALAVIFDataset::CreateCopy(const char *pszFilename, if (nBands != 1 && nBands != 2 && nBands != 3 && nBands != 4) { CPLError(CE_Failure, CPLE_NotSupported, - "Unsupported number of bands: only 1 (Gray), 2 (Graph+Alpha) " + "Unsupported number of bands: only 1 (Gray), 2 (Gray+Alpha), " "3 (RGB) or 4 (RGBA) bands are supported"); return nullptr; } @@ -1163,7 +1147,7 @@ void GDALRegister_AVIF() bool bMayHaveWriteSupport = true; if (!poDM->IsKnownDriver("AVIF")) { - // If we are not built as a defered plugin, check now if libavif has + // If we are not built as a deferred plugin, check now if libavif has // write support bMayHaveWriteSupport = poDriver->GetMetadataItem(GDAL_DMD_CREATIONOPTIONLIST) != nullptr; diff --git a/frmts/avif/avifdrivercore.cpp b/frmts/avif/avifdrivercore.cpp index f6b6d9d2578b..9a791903e7f1 100644 --- a/frmts/avif/avifdrivercore.cpp +++ b/frmts/avif/avifdrivercore.cpp @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2024, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "avifdrivercore.h" diff --git a/frmts/avif/avifdrivercore.h b/frmts/avif/avifdrivercore.h index 8499e6c1bc18..8706df3f0dfd 100644 --- a/frmts/avif/avifdrivercore.h +++ b/frmts/avif/avifdrivercore.h @@ -6,23 +6,7 @@ ****************************************************************************** * Copyright (c) 2024, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef AVIFDRIVERCORE_H diff --git a/frmts/basisu_ktx2/basisudataset.cpp b/frmts/basisu_ktx2/basisudataset.cpp index 0a78ab1b3bfa..94bda23c3e95 100644 --- a/frmts/basisu_ktx2/basisudataset.cpp +++ b/frmts/basisu_ktx2/basisudataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_pam.h" diff --git a/frmts/basisu_ktx2/basisudrivercore.cpp b/frmts/basisu_ktx2/basisudrivercore.cpp index 7f30e0eec6e8..1f1048e31865 100644 --- a/frmts/basisu_ktx2/basisudrivercore.cpp +++ b/frmts/basisu_ktx2/basisudrivercore.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "basisudrivercore.h" diff --git a/frmts/basisu_ktx2/basisudrivercore.h b/frmts/basisu_ktx2/basisudrivercore.h index 26723f7e45d4..86291583bb44 100644 --- a/frmts/basisu_ktx2/basisudrivercore.h +++ b/frmts/basisu_ktx2/basisudrivercore.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef BASISUDRIVERCORE_H diff --git a/frmts/basisu_ktx2/common.cpp b/frmts/basisu_ktx2/common.cpp index 98a856100bca..91f7b22e39c1 100644 --- a/frmts/basisu_ktx2/common.cpp +++ b/frmts/basisu_ktx2/common.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_frmts.h" diff --git a/frmts/basisu_ktx2/common.h b/frmts/basisu_ktx2/common.h index 651642b94cfa..ee3314a66cce 100644 --- a/frmts/basisu_ktx2/common.h +++ b/frmts/basisu_ktx2/common.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_priv.h" diff --git a/frmts/basisu_ktx2/commoncore.cpp b/frmts/basisu_ktx2/commoncore.cpp index 9707fde8eb03..a59c686dd67e 100644 --- a/frmts/basisu_ktx2/commoncore.cpp +++ b/frmts/basisu_ktx2/commoncore.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "commoncore.h" diff --git a/frmts/basisu_ktx2/commoncore.h b/frmts/basisu_ktx2/commoncore.h index 6dc1fa5e0bb5..a96b3f22b643 100644 --- a/frmts/basisu_ktx2/commoncore.h +++ b/frmts/basisu_ktx2/commoncore.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include diff --git a/frmts/basisu_ktx2/include_basisu_sdk.h b/frmts/basisu_ktx2/include_basisu_sdk.h index a3e726b82d0b..7e317c80bc2c 100644 --- a/frmts/basisu_ktx2/include_basisu_sdk.h +++ b/frmts/basisu_ktx2/include_basisu_sdk.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_port.h" diff --git a/frmts/basisu_ktx2/ktx2dataset.cpp b/frmts/basisu_ktx2/ktx2dataset.cpp index 0f8e46d17d04..ca9f64dfdeaa 100644 --- a/frmts/basisu_ktx2/ktx2dataset.cpp +++ b/frmts/basisu_ktx2/ktx2dataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_pam.h" diff --git a/frmts/basisu_ktx2/ktx2drivercore.cpp b/frmts/basisu_ktx2/ktx2drivercore.cpp index 691c77539490..1c98d03d50e9 100644 --- a/frmts/basisu_ktx2/ktx2drivercore.cpp +++ b/frmts/basisu_ktx2/ktx2drivercore.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ktx2drivercore.h" diff --git a/frmts/basisu_ktx2/ktx2drivercore.h b/frmts/basisu_ktx2/ktx2drivercore.h index 23729a5e0fa8..65bd35fce0ce 100644 --- a/frmts/basisu_ktx2/ktx2drivercore.h +++ b/frmts/basisu_ktx2/ktx2drivercore.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2022, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef KTX2DRIVERCORE_H diff --git a/frmts/blx/blx.c b/frmts/blx/blx.c index 25daaff15835..ec0df53ab1d2 100644 --- a/frmts/blx/blx.c +++ b/frmts/blx/blx.c @@ -3,26 +3,7 @@ * Copyright (c) 2008, Henrik Johansson * Copyright (c) 2008-2009, 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. + * SPDX-License-Identifier: MIT */ #include "blx.h" diff --git a/frmts/blx/blx.h b/frmts/blx/blx.h index 69e3ee59557a..0a0de2a8ded8 100644 --- a/frmts/blx/blx.h +++ b/frmts/blx/blx.h @@ -2,26 +2,7 @@ * * Copyright (c) 2008, Henrik Johansson * - * 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. + * SPDX-License-Identifier: MIT */ #ifndef BLX_H_INCLUDED diff --git a/frmts/blx/blxdataset.cpp b/frmts/blx/blxdataset.cpp index 6e51f519c965..9342391baa28 100644 --- a/frmts/blx/blxdataset.cpp +++ b/frmts/blx/blxdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2006, Henrik Johansson * Copyright (c) 2008-2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************** * */ diff --git a/frmts/bmp/bmpdataset.cpp b/frmts/bmp/bmpdataset.cpp index f420e3de59dc..e2dd0c87196a 100644 --- a/frmts/bmp/bmpdataset.cpp +++ b/frmts/bmp/bmpdataset.cpp @@ -9,23 +9,7 @@ * Copyright (c) 2002, Andrey Kiselev * Copyright (c) 2007-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_string.h" diff --git a/frmts/bsb/bsb2raw.c b/frmts/bsb/bsb2raw.c index c396fc49a7fd..9758b84d4913 100644 --- a/frmts/bsb/bsb2raw.c +++ b/frmts/bsb/bsb2raw.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_error.h" diff --git a/frmts/bsb/bsb_read.c b/frmts/bsb/bsb_read.c index acc3b127cd45..8f437bde0fff 100644 --- a/frmts/bsb/bsb_read.c +++ b/frmts/bsb/bsb_read.c @@ -14,23 +14,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "bsb_read.h" diff --git a/frmts/bsb/bsb_read.h b/frmts/bsb/bsb_read.h index 6c314f9829cc..95e191853dfc 100644 --- a/frmts/bsb/bsb_read.h +++ b/frmts/bsb/bsb_read.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef BSBREAD_H_INCLUDED diff --git a/frmts/bsb/bsbdataset.cpp b/frmts/bsb/bsbdataset.cpp index cf5f6f0f88ea..e2bdb34154ba 100644 --- a/frmts/bsb/bsbdataset.cpp +++ b/frmts/bsb/bsbdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2008-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "bsb_read.h" diff --git a/frmts/cals/calsdataset.cpp b/frmts/cals/calsdataset.cpp index f8267075379f..48ad43ef730f 100644 --- a/frmts/cals/calsdataset.cpp +++ b/frmts/cals/calsdataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_frmts.h" @@ -331,7 +315,7 @@ GDALDataset *CALSDataset::Open(GDALOpenInfo *poOpenInfo) // Create a TIFF header for a single-strip CCITTFAX4 file. poDS->osTIFFHeaderFilename = - CPLSPrintf("/vsimem/cals/header_%p.tiff", poDS); + VSIMemGenerateHiddenFilename("cals_header.tiff"); VSILFILE *fp = VSIFOpenL(poDS->osTIFFHeaderFilename, "wb"); const int nTagCount = 10; const int nHeaderSize = 4 + 4 + 2 + nTagCount * 12 + 4; @@ -359,7 +343,7 @@ GDALDataset *CALSDataset::Open(GDALOpenInfo *poOpenInfo) // Create a /vsisparse/ description file assembling the TIFF header // with the FAX4 codestream that starts at offset 2048 of the CALS file. - poDS->osSparseFilename = CPLSPrintf("/vsimem/cals/sparse_%p.xml", poDS); + poDS->osSparseFilename = VSIMemGenerateHiddenFilename("cals_sparse.xml"); fp = VSIFOpenL(poDS->osSparseFilename, "wb"); CPLAssert(fp); VSIFPrintfL(fp, @@ -473,7 +457,8 @@ GDALDataset *CALSDataset::CreateCopy(const char *pszFilename, // Write a in-memory TIFF with just the TIFF header to figure out // how large it will be. - CPLString osTmpFilename(CPLSPrintf("/vsimem/cals/tmp_%p", poSrcDS)); + const CPLString osTmpFilename( + VSIMemGenerateHiddenFilename("tmp_tif_header")); char **papszOptions = nullptr; papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "CCITTFAX4"); papszOptions = CSLSetNameValue(papszOptions, "NBITS", "1"); diff --git a/frmts/ceos/ceosdataset.cpp b/frmts/ceos/ceosdataset.cpp index 96606f63322b..4720dd90b2c7 100644 --- a/frmts/ceos/ceosdataset.cpp +++ b/frmts/ceos/ceosdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2009-2010, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceosopen.h" diff --git a/frmts/ceos/ceosopen.c b/frmts/ceos/ceosopen.c index f7e6cbd725fb..aa3c83d80d5d 100644 --- a/frmts/ceos/ceosopen.c +++ b/frmts/ceos/ceosopen.c @@ -9,23 +9,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2007-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceosopen.h" diff --git a/frmts/ceos/ceosopen.h b/frmts/ceos/ceosopen.h index 1036155c50af..f1c8fde51a7e 100644 --- a/frmts/ceos/ceosopen.h +++ b/frmts/ceos/ceosopen.h @@ -9,23 +9,7 @@ ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef CEOSOPEN_H_INCLUDED diff --git a/frmts/ceos/ceostest.c b/frmts/ceos/ceostest.c index 95436d85b063..6ad4726b1bf8 100644 --- a/frmts/ceos/ceostest.c +++ b/frmts/ceos/ceostest.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceosopen.h" diff --git a/frmts/ceos2/ceos.c b/frmts/ceos2/ceos.c index 461a91668fb8..5104882db32f 100644 --- a/frmts/ceos2/ceos.c +++ b/frmts/ceos2/ceos.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2000, Atlantis Scientific Inc * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceos.h" diff --git a/frmts/ceos2/ceos.h b/frmts/ceos2/ceos.h index 64a39b1cba10..54fd760396e8 100644 --- a/frmts/ceos2/ceos.h +++ b/frmts/ceos2/ceos.h @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2000, Atlantis Scientific Inc * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef CEOS_H diff --git a/frmts/ceos2/ceosrecipe.c b/frmts/ceos2/ceosrecipe.c index 352bcaae5758..82a0960f6c12 100644 --- a/frmts/ceos2/ceosrecipe.c +++ b/frmts/ceos2/ceosrecipe.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2000, Atlantis Scientific Inc * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceos.h" diff --git a/frmts/ceos2/ceossar.c b/frmts/ceos2/ceossar.c index 03cd7d31e15c..405147b44089 100644 --- a/frmts/ceos2/ceossar.c +++ b/frmts/ceos2/ceossar.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2000, Atlantis Scientific Inc * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceos.h" diff --git a/frmts/ceos2/link.c b/frmts/ceos2/link.c index 472e4024f66b..769984cb23d6 100644 --- a/frmts/ceos2/link.c +++ b/frmts/ceos2/link.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2000, Atlantis Scientific Inc * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceos.h" diff --git a/frmts/ceos2/sar_ceosdataset.cpp b/frmts/ceos2/sar_ceosdataset.cpp index 545221838aa5..eb5347088eaf 100644 --- a/frmts/ceos2/sar_ceosdataset.cpp +++ b/frmts/ceos2/sar_ceosdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2000, Atlantis Scientific Inc. * Copyright (c) 2009-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "ceos.h" diff --git a/frmts/coasp/coasp_dataset.cpp b/frmts/coasp/coasp_dataset.cpp index 562245774263..3db8b729a0cf 100644 --- a/frmts/coasp/coasp_dataset.cpp +++ b/frmts/coasp/coasp_dataset.cpp @@ -13,23 +13,7 @@ * Copyright (c) 2007, Philippe Vachon * Copyright (c) 2009-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_conv.h" diff --git a/frmts/cosar/cosar_dataset.cpp b/frmts/cosar/cosar_dataset.cpp index f7494f47b79e..a136dbba39fd 100644 --- a/frmts/cosar/cosar_dataset.cpp +++ b/frmts/cosar/cosar_dataset.cpp @@ -1,23 +1,7 @@ /* TerraSAR-X COSAR Format Driver * (C)2007 Philippe P. Vachon * --------------------------------------------------------------------------- - * 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. + * SPDX-License-Identifier: MIT */ #include "cpl_conv.h" diff --git a/frmts/ctg/ctgdataset.cpp b/frmts/ctg/ctgdataset.cpp index d133cdf4f6e7..000ec386a5bb 100644 --- a/frmts/ctg/ctgdataset.cpp +++ b/frmts/ctg/ctgdataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2011, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_frmts.h" diff --git a/frmts/daas/daasdataset.cpp b/frmts/daas/daasdataset.cpp index 0c68c9e31439..c2d5e6778e2b 100644 --- a/frmts/daas/daasdataset.cpp +++ b/frmts/daas/daasdataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2018-2019, Airbus DS Intelligence * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_http.h" @@ -2420,7 +2404,7 @@ CPLErr GDALDAASRasterBand::GetBlocks(int nBlockXOff, int nBlockYOff, } else { - CPLString osTmpMemFile = CPLSPrintf("/vsimem/daas_%p", this); + const CPLString osTmpMemFile = VSIMemGenerateHiddenFilename("daas"); VSIFCloseL(VSIFileFromMemBuffer( osTmpMemFile, psResult->pasMimePart[iDataPart].pabyData, psResult->pasMimePart[iDataPart].nDataLen, false)); diff --git a/frmts/dds/crunch_headers.h b/frmts/dds/crunch_headers.h index 0fef5f224fc4..70511bbf5aa7 100644 --- a/frmts/dds/crunch_headers.h +++ b/frmts/dds/crunch_headers.h @@ -7,23 +7,7 @@ ****************************************************************************** * 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. + * SPDX-License-Identifier: MIT ****************************************************************************** */ diff --git a/frmts/dds/ddsdataset.cpp b/frmts/dds/ddsdataset.cpp index 5c620f78ff0d..3e3a19e29081 100644 --- a/frmts/dds/ddsdataset.cpp +++ b/frmts/dds/ddsdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2013, Alan Boudreault * Copyright (c) 2013,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. + * SPDX-License-Identifier: MIT ******************************************************************************/ #include "crunch_headers.h" diff --git a/frmts/dds/ddsdrivercore.cpp b/frmts/dds/ddsdrivercore.cpp index f4a9a4bd3e63..6bbe7d8a0686 100644 --- a/frmts/dds/ddsdrivercore.cpp +++ b/frmts/dds/ddsdrivercore.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2013, Alan Boudreault * Copyright (c) 2013,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. + * SPDX-License-Identifier: MIT ******************************************************************************/ #include "ddsdrivercore.h" diff --git a/frmts/dds/ddsdrivercore.h b/frmts/dds/ddsdrivercore.h index 31f4274aafa1..fb79cb03ae0c 100644 --- a/frmts/dds/ddsdrivercore.h +++ b/frmts/dds/ddsdrivercore.h @@ -8,23 +8,7 @@ * Copyright (c) 2013, Alan Boudreault * Copyright (c) 2013,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. + * SPDX-License-Identifier: MIT ******************************************************************************/ #ifndef DDSDRIVERCORE_H diff --git a/frmts/derived/deriveddataset.cpp b/frmts/derived/deriveddataset.cpp index f73c2386de7f..bccbf31501db 100644 --- a/frmts/derived/deriveddataset.cpp +++ b/frmts/derived/deriveddataset.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2016 Julien Michel * - * 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #include "../vrt/vrtdataset.h" #include "gdal_pam.h" diff --git a/frmts/derived/derivedlist.c b/frmts/derived/derivedlist.c index 15f44373ea8a..6f004ef245e3 100644 --- a/frmts/derived/derivedlist.c +++ b/frmts/derived/derivedlist.c @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2016 Julien Michel * - * 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #include "derivedlist.h" #include "gdal.h" diff --git a/frmts/derived/derivedlist.h b/frmts/derived/derivedlist.h index 5c0885ebe9cf..b2de0cd10434 100644 --- a/frmts/derived/derivedlist.h +++ b/frmts/derived/derivedlist.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2016 Julien Michel * - * 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #ifndef DERIVEDLIST_H_INCLUDED #define DERIVEDLIST_H_INCLUDED diff --git a/frmts/dimap/dimapdataset.cpp b/frmts/dimap/dimapdataset.cpp index 9fe68c998b05..007b9a2024b9 100644 --- a/frmts/dimap/dimapdataset.cpp +++ b/frmts/dimap/dimapdataset.cpp @@ -10,23 +10,7 @@ * Copyright (c) 2007, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_minixml.h" @@ -826,8 +810,8 @@ int DIMAPDataset::ReadImageInformation() /* Try and open the file. */ /* -------------------------------------------------------------------- */ - auto poImageDS = - std::unique_ptr(GDALDataset::Open(osImageFilename)); + auto poImageDS = std::unique_ptr(GDALDataset::Open( + osImageFilename, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR)); if (poImageDS == nullptr) { return FALSE; @@ -1233,8 +1217,8 @@ int DIMAPDataset::ReadImageInformation2() /* -------------------------------------------------------------------- */ /* Try and open the file. */ /* -------------------------------------------------------------------- */ - auto poImageDS = - std::unique_ptr(GDALDataset::Open(osImageDSFilename)); + auto poImageDS = std::unique_ptr(GDALDataset::Open( + osImageDSFilename, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR)); if (poImageDS == nullptr) { return FALSE; @@ -1416,16 +1400,19 @@ int DIMAPDataset::ReadImageInformation2() } case 4: { + poBand->SetColorInterpretation(GCI_NIRBand); poBand->SetDescription("NIR"); break; } case 5: { + poBand->SetColorInterpretation(GCI_RedEdgeBand); poBand->SetDescription("Red Edge"); break; } case 6: { + poBand->SetColorInterpretation(GCI_CoastalBand); poBand->SetDescription("Deep Blue"); break; } @@ -1433,6 +1420,11 @@ int DIMAPDataset::ReadImageInformation2() break; } } + else if (l_nBands == 1 && osSpectralProcessing == "PAN") + { + poBand->SetColorInterpretation(GCI_PanBand); + poBand->SetDescription("Panchromatic"); + } SetBand(iBand, poBand); } diff --git a/frmts/drivers.ini b/frmts/drivers.ini index c05e28e5c948..11d381945755 100644 --- a/frmts/drivers.ini +++ b/frmts/drivers.ini @@ -12,8 +12,9 @@ [order] VRT -GTI Derived +GTI +SNAP_TIFF GTiff COG NITF @@ -69,7 +70,6 @@ TIL ERS JP2KAK JPIPKAK -JP2Lura ECW JP2ECW JP2OpenJPEG @@ -181,7 +181,6 @@ GNMDatabase # End of GNM drivers # Beginning OGR drivers -DB2 ESRI Shapefile MapInfo File UK .NTF @@ -265,12 +264,16 @@ PMTiles JSONFG MiraMonVector XODR +ADBC # Put TIGER and AVCBIN at end since they need poOpenInfo->GetSiblingFiles() Tiger AVCBin AVCE00 +# Last but not the least +AIVector + # End of OGR drivers # Put here drivers that absolutely need to look for side car @@ -280,6 +283,7 @@ ENVI EHdr ISCE Zarr +RCM # Register GDAL HTTP last, to let a chance to other drivers # accepting URL to handle them before diff --git a/frmts/dted/dted_api.c b/frmts/dted/dted_api.c index 825d5c68a65d..2cbe82c02506 100644 --- a/frmts/dted/dted_api.c +++ b/frmts/dted/dted_api.c @@ -9,23 +9,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2007-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "dted_api.h" diff --git a/frmts/dted/dted_api.h b/frmts/dted/dted_api.h index 4bf573450bdd..3d7d61793f4a 100644 --- a/frmts/dted/dted_api.h +++ b/frmts/dted/dted_api.h @@ -9,23 +9,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2007-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef DTED_API_H_INCLUDED diff --git a/frmts/dted/dted_create.c b/frmts/dted/dted_create.c index 288dd00bdd0f..47efd71fbc16 100644 --- a/frmts/dted/dted_create.c +++ b/frmts/dted/dted_create.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "dted_api.h" diff --git a/frmts/dted/dted_ptstream.c b/frmts/dted/dted_ptstream.c index 08161adead73..6dbd11563652 100644 --- a/frmts/dted/dted_ptstream.c +++ b/frmts/dted/dted_ptstream.c @@ -8,23 +8,7 @@ ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "dted_api.h" diff --git a/frmts/dted/dted_test.c b/frmts/dted/dted_test.c index 2508236de3ea..0ee60a4454f2 100644 --- a/frmts/dted/dted_test.c +++ b/frmts/dted/dted_test.c @@ -9,23 +9,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007, 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #include "gdal.h" diff --git a/frmts/dted/dteddataset.cpp b/frmts/dted/dteddataset.cpp index 9ed5b38df56f..47cac394e5e9 100644 --- a/frmts/dted/dteddataset.cpp +++ b/frmts/dted/dteddataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 1999, Frank Warmerdam * Copyright (c) 2007-2012, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "dted_api.h" diff --git a/frmts/ecw/ecwasyncreader.cpp b/frmts/ecw/ecwasyncreader.cpp index 21b9d764e40e..fcca60c4b778 100644 --- a/frmts/ecw/ecwasyncreader.cpp +++ b/frmts/ecw/ecwasyncreader.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2011, Frank Warmerdam * Copyright (c) 2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // ncsjpcbuffer.h needs the min and max macros. diff --git a/frmts/ecw/ecwcreatecopy.cpp b/frmts/ecw/ecwcreatecopy.cpp index 5654e382cd57..525bb65d9ad6 100644 --- a/frmts/ecw/ecwcreatecopy.cpp +++ b/frmts/ecw/ecwcreatecopy.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2001, 2004, Frank Warmerdam * Copyright (c) 2008-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // ncsjpcbuffer.h needs the min and max macros. diff --git a/frmts/ecw/ecwdataset.cpp b/frmts/ecw/ecwdataset.cpp index dd7bde5a9b1a..933c07eb4149 100644 --- a/frmts/ecw/ecwdataset.cpp +++ b/frmts/ecw/ecwdataset.cpp @@ -8,23 +8,7 @@ * Copyright (c) 2001, Frank Warmerdam * Copyright (c) 2007-2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // ncsjpcbuffer.h needs the min and max macros. @@ -40,6 +24,7 @@ #include "ecwdrivercore.h" +#include #include #undef NOISY_DEBUG @@ -49,7 +34,7 @@ static int bNCSInitialized = FALSE; void ECWInitialize(void); -#define BLOCK_SIZE 256 +constexpr int DEFAULT_BLOCK_SIZE = 256; GDALDataset *ECWDatasetOpenJPEG2000(GDALOpenInfo *poOpenInfo); @@ -87,8 +72,39 @@ ECWRasterBand::ECWRasterBand(ECWDataset *poDSIn, int nBandIn, int iOverviewIn, nRasterXSize = poDS->GetRasterXSize() / (1 << (iOverview + 1)); nRasterYSize = poDS->GetRasterYSize() / (1 << (iOverview + 1)); - nBlockXSize = BLOCK_SIZE; - nBlockYSize = BLOCK_SIZE; +#if ECWSDK_VERSION >= 51 + if (poDSIn->bIsJPEG2000 && poDSIn->poFileView) + { + UINT32 nTileWidth = 0; + poDSIn->poFileView->GetParameter( + const_cast("JPC:DECOMPRESS:TILESIZE:X"), &nTileWidth); + if (nTileWidth <= static_cast(INT_MAX)) + { + nBlockXSize = static_cast(nTileWidth); + } + nBlockXSize = MIN(nBlockXSize, nRasterXSize); + + UINT32 nTileHeight = 0; + poDSIn->poFileView->GetParameter( + const_cast("JPC:DECOMPRESS:TILESIZE:Y"), &nTileHeight); + if (nTileHeight <= static_cast(INT_MAX)) + { + nBlockYSize = static_cast(nTileHeight); + } + nBlockYSize = MIN(nBlockYSize, nRasterYSize); + } +#endif + + // Slightly arbitrary value. Too large values would defeat the purpose + // of the block concept. + constexpr int LIMIT_FOR_BLOCK_SIZE = 2048; + if (nBlockXSize <= 0 || nBlockYSize <= 0 || + nBlockXSize > LIMIT_FOR_BLOCK_SIZE || + nBlockYSize > LIMIT_FOR_BLOCK_SIZE) + { + nBlockXSize = DEFAULT_BLOCK_SIZE; + nBlockYSize = DEFAULT_BLOCK_SIZE; + } /* -------------------------------------------------------------------- */ /* Work out band color interpretation. */ @@ -2850,10 +2866,11 @@ GDALDataset *ECWDataset::Open(GDALOpenInfo *poOpenInfo, int bIsJPEG2000) /* There are issues at least in the 5.x series. */ /* -------------------------------------------------------------------- */ #if ECWSDK_VERSION >= 40 + constexpr const char *szDETECT_BUG_FILENAME = + "__detect_ecw_uint32_bug__.j2k"; if (bIsJPEG2000 && poDS->eNCSRequestDataType == NCSCT_UINT32 && CPLTestBool(CPLGetConfigOption("ECW_CHECK_CORRECT_DECODING", "TRUE")) && - !STARTS_WITH_CI(poOpenInfo->pszFilename, - "/vsimem/detect_ecw_uint32_bug")) + strstr(poOpenInfo->pszFilename, szDETECT_BUG_FILENAME) == nullptr) { static bool bUINT32_Ok = false; { @@ -2878,7 +2895,7 @@ GDALDataset *ECWDataset::Open(GDALOpenInfo *poOpenInfo, int bIsJPEG2000) 0xDF, 0xFF, 0x7F, 0x5F, 0xFF, 0xD9}; const std::string osTmpFilename = - CPLSPrintf("/vsimem/detect_ecw_uint32_bug_%p.j2k", poDS); + VSIMemGenerateHiddenFilename(szDETECT_BUG_FILENAME); VSIFCloseL(VSIFileFromMemBuffer( osTmpFilename.c_str(), const_cast(abyTestUInt32ImageData), diff --git a/frmts/ecw/ecwdrivercore.cpp b/frmts/ecw/ecwdrivercore.cpp index 3fa405a82418..ec48d73a8113 100644 --- a/frmts/ecw/ecwdrivercore.cpp +++ b/frmts/ecw/ecwdrivercore.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // ncsjpcbuffer.h needs the min and max macros. diff --git a/frmts/ecw/ecwdrivercore.h b/frmts/ecw/ecwdrivercore.h index dedc043a0ac0..eb5d79ff1c46 100644 --- a/frmts/ecw/ecwdrivercore.h +++ b/frmts/ecw/ecwdrivercore.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2023, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef ECWDRIVERCORE_H diff --git a/frmts/ecw/ecwsdk_headers.h b/frmts/ecw/ecwsdk_headers.h index b2218deb36b5..e9e390819dbb 100644 --- a/frmts/ecw/ecwsdk_headers.h +++ b/frmts/ecw/ecwsdk_headers.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2015, 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. + * SPDX-License-Identifier: MIT *****************************************************************************/ #ifndef ECWSDK_HEADERS_H diff --git a/frmts/ecw/gdal_ecw.h b/frmts/ecw/gdal_ecw.h index b60aa3ccc314..a6eed743c0bf 100644 --- a/frmts/ecw/gdal_ecw.h +++ b/frmts/ecw/gdal_ecw.h @@ -9,23 +9,7 @@ * Copyright (c) 2001-2011, Frank Warmerdam * Copyright (c) 2013, 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef GDAL_ECW_H_INCLUDED diff --git a/frmts/ecw/jp2userbox.cpp b/frmts/ecw/jp2userbox.cpp index 4a2d12a6462d..e5effa0191d4 100644 --- a/frmts/ecw/jp2userbox.cpp +++ b/frmts/ecw/jp2userbox.cpp @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2005, Frank Warmerdam * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ // ncsjpcbuffer.h needs the min and max macros. diff --git a/frmts/ecw/lookup.py b/frmts/ecw/lookup.py index a2710d28fffb..a8a3d1d7693f 100644 --- a/frmts/ecw/lookup.py +++ b/frmts/ecw/lookup.py @@ -9,23 +9,7 @@ # ****************************************************************************** # Copyright (c) 2003, Frank Warmerdam # -# 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. +# SPDX-License-Identifier: MIT # ****************************************************************************** import osr diff --git a/frmts/eeda/CMakeLists.txt b/frmts/eeda/CMakeLists.txt index 716ae8385688..d531229bb5b6 100644 --- a/frmts/eeda/CMakeLists.txt +++ b/frmts/eeda/CMakeLists.txt @@ -8,7 +8,6 @@ add_gdal_driver( "NOT GDAL_USE_JSONC_INTERNAL" NO_DEPS) gdal_standard_includes(gdal_EEDA) -target_include_directories(gdal_EEDA PRIVATE $) set(GDAL_DATA_FILES LICENSE.TXT diff --git a/frmts/eeda/eeda.h b/frmts/eeda/eeda.h index c2cfcaec55e7..02cc091a1cf5 100644 --- a/frmts/eeda/eeda.h +++ b/frmts/eeda/eeda.h @@ -7,23 +7,7 @@ ****************************************************************************** * Copyright (c) 2017-2018, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef EEDA_H_INCLUDED diff --git a/frmts/eeda/eedacommon.cpp b/frmts/eeda/eedacommon.cpp index 0ba2c6a82492..91832dc5fa0b 100644 --- a/frmts/eeda/eedacommon.cpp +++ b/frmts/eeda/eedacommon.cpp @@ -7,28 +7,12 @@ ****************************************************************************** * Copyright (c) 2017-2018, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "cpl_http.h" #include "eeda.h" -#include "ogrgeojsonreader.h" +#include "ogrlibjsonutils.h" #include #include @@ -386,8 +370,15 @@ char **GDALEEDABaseDataset::GetBaseHTTPOptions() } } - CPLString osServiceAccountJson( - CPLGetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", "")); + CPLString osServiceAccountJson; + const char *pszVSIPath = + CSLFetchNameValue(papszOpenOptions, "VSI_PATH_FOR_AUTH"); + if (pszVSIPath) + osServiceAccountJson = VSIGetPathSpecificOption( + pszVSIPath, "GOOGLE_APPLICATION_CREDENTIALS", ""); + if (osServiceAccountJson.empty()) + osServiceAccountJson = + CPLGetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", ""); if (!osServiceAccountJson.empty()) { CPLJSONDocument oDoc; @@ -443,7 +434,8 @@ char **GDALEEDABaseDataset::GetBaseHTTPOptions() "Missing EEDA_BEARER, EEDA_BEARER_FILE or " "GOOGLE_APPLICATION_CREDENTIALS or " "EEDA_PRIVATE_KEY/EEDA_PRIVATE_KEY_FILE + " - "EEDA_CLIENT_EMAIL config option"); + "EEDA_CLIENT_EMAIL config option or " + "VSI_PATH_FOR_AUTH open option"); CSLDestroy(papszOptions); return nullptr; } diff --git a/frmts/eeda/eedadataset.cpp b/frmts/eeda/eedadataset.cpp index f41c4b4781d3..2053415bf6c8 100644 --- a/frmts/eeda/eedadataset.cpp +++ b/frmts/eeda/eedadataset.cpp @@ -7,30 +7,14 @@ ****************************************************************************** * Copyright (c) 2017-2018, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_priv.h" +#include "ogrsf_frmts.h" #include "cpl_http.h" #include "cpl_conv.h" -#include "ogrgeojsonreader.h" -#include "ogrgeojsonwriter.h" +#include "ogrlibjsonutils.h" #include "ogr_swq.h" #include "eeda.h" @@ -1245,11 +1229,16 @@ void GDALRegister_EEDA() poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Earth Engine Data API"); poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/eeda.html"); poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "EEDA:"); - poDriver->SetMetadataItem(GDAL_DMD_OPENOPTIONLIST, - "" - " "); + poDriver->SetMetadataItem( + GDAL_DMD_OPENOPTIONLIST, + "" + " "); poDriver->pfnOpen = GDALEEDAOpen; poDriver->pfnIdentify = GDALEEDAdentify; diff --git a/frmts/eeda/eedaidataset.cpp b/frmts/eeda/eedaidataset.cpp index 9a6c41be78b8..23d5ba99d17b 100644 --- a/frmts/eeda/eedaidataset.cpp +++ b/frmts/eeda/eedaidataset.cpp @@ -7,30 +7,13 @@ ****************************************************************************** * Copyright (c) 2017-2018, Planet Labs * - * 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. + * SPDX-License-Identifier: MIT ****************************************************************************/ #include "gdal_priv.h" #include "cpl_http.h" #include "cpl_conv.h" -#include "ogrgeojsonreader.h" -#include "ogrgeojsonwriter.h" +#include "ogrlibjsonutils.h" #include "eeda.h" #include @@ -433,7 +416,7 @@ bool GDALEEDAIRasterBand::DecodeGDALDataset(const GByte *pabyData, int nDataLen, { GDALEEDAIDataset *poGDS = reinterpret_cast(poDS); - CPLString osTmpFilename(CPLSPrintf("/vsimem/eeai/%p", this)); + const CPLString osTmpFilename(VSIMemGenerateHiddenFilename("eedai")); VSIFCloseL(VSIFileFromMemBuffer( osTmpFilename, const_cast(pabyData), nDataLen, false)); const char *const apszDrivers[] = {"PNG", "JPEG", "GTIFF", nullptr}; @@ -1558,6 +1541,10 @@ void GDALRegister_EEDAI() " " "