diff --git a/.github/workflows/publish-windows.yml b/.github/workflows/publish-windows.yml index 02fcd2474..72c15e1bd 100644 --- a/.github/workflows/publish-windows.yml +++ b/.github/workflows/publish-windows.yml @@ -21,7 +21,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.12.10' + python-version: '3.12.9' architecture: 'x64' - uses: Jimver/cuda-toolkit@v0.2.24 id: cuda-toolkit diff --git a/.github/workflows/test-build-prs.yaml b/.github/workflows/test-build-prs.yaml index 1656ba5c2..fef51196c 100644 --- a/.github/workflows/test-build-prs.yaml +++ b/.github/workflows/test-build-prs.yaml @@ -56,7 +56,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.12.10' + python-version: '3.12.9' architecture: 'x64' - uses: Jimver/cuda-toolkit@v0.2.24 id: cuda-toolkit diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 39a058053..967271323 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -85,41 +85,43 @@ mark_as_advanced(SB_BINARY_DIR) message(STATUS "SuperBuild binary files will be located to: ${SB_BINARY_DIR}") if (WIN32) - if (NOT DEFINED CMAKE_TOOLCHAIN_FILE) - message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE not set. You need to set it to the path of vcpkg.cmake") - endif() - get_filename_component(CMAKE_TOOLCHAIN_DIR ${CMAKE_TOOLCHAIN_FILE} DIRECTORY) - get_filename_component(VCPKG_ROOT "${CMAKE_TOOLCHAIN_DIR}/../../" ABSOLUTE) - set(WIN32_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") - set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") - set(PYTHON_EXE_PATH "${PYTHON_HOME}/Scripts/python") - - # Use the GDAL version that comes with pip - set(GDAL_ROOT "${PYTHON_HOME}/Lib/site-packages/osgeo") - set(GDAL_LIBRARY "${GDAL_ROOT}/gdal.lib") - set(GDAL_INCLUDE_DIR "${GDAL_ROOT}/include/gdal") - - message("Copying VCPKG DLLs...") - file(GLOB COPY_DLLS "${VCPKG_ROOT}/installed/x64-windows/bin/*.dll") - file(COPY ${COPY_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") - - message("Copying CUDA DLLs...") - file(GLOB CUDA_DLLS "$ENV{CUDA_PATH}/bin/cudart64*.dll") - file(COPY ${CUDA_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") - - set(WIN32_GDAL_ARGS -DGDAL_FOUND=TRUE -DGDAL_LIBRARY=${GDAL_LIBRARY} -DGDAL_INCLUDE_DIR=${GDAL_INCLUDE_DIR}) + if (NOT DEFINED CMAKE_TOOLCHAIN_FILE) + message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE not set. You need to set it to the path of vcpkg.cmake") + endif() + get_filename_component(CMAKE_TOOLCHAIN_DIR ${CMAKE_TOOLCHAIN_FILE} DIRECTORY) + get_filename_component(VCPKG_ROOT "${CMAKE_TOOLCHAIN_DIR}/../../" ABSOLUTE) + set(WIN32_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") + set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") + set(PYTHON_EXE_PATH "${PYTHON_HOME}/Scripts/python") + + message("Copying VCPKG DLLs...") + file(GLOB COPY_DLLS "${VCPKG_ROOT}/installed/x64-windows/bin/*.dll") + file(COPY ${COPY_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") + + message("Copying CUDA DLLs...") + file(GLOB CUDA_DLLS "$ENV{CUDA_PATH}/bin/cudart64*.dll") + file(COPY ${CUDA_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") + + message("Copying GDAL tools...") + file(GLOB GDAL_TOOLS "${VCPKG_ROOT}/installed/x64-windows/tools/gdal/*") + file(COPY ${GDAL_TOOLS} DESTINATION "${SB_INSTALL_DIR}/bin") + + message("Copying GDAL data...") + file(GLOB GDAL_DATA "${VCPKG_ROOT}/installed/x64-windows/share/gdal/*") + file(COPY ${GDAL_DATA} DESTINATION "${SB_INSTALL_DIR}/bin/data/gdal") + + message("Copying PROJ data...") + file(GLOB PROJ_DATA "${VCPKG_ROOT}/installed/x64-windows/share/proj/*") + file(COPY ${PROJ_DATA} DESTINATION "${SB_INSTALL_DIR}/bin/data/proj") + + # GDAL comes from vcpkg, create a dummy target to satisfy dependencies + add_custom_target(gdal) elseif(APPLE) set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") set(PYTHON_EXE_PATH "${PYTHON_HOME}/bin/python") - set(GDAL_ROOT "${SB_INSTALL_DIR}") - set(GDAL_LIBRARY "${GDAL_ROOT}/lib/libgdal.dylib") - set(GDAL_INCLUDE_DIR "${GDAL_ROOT}/include") else() set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") set(PYTHON_EXE_PATH "${PYTHON_HOME}/bin/python3") - set(GDAL_ROOT "${SB_INSTALL_DIR}") - set(GDAL_LIBRARY "${GDAL_ROOT}/lib/libgdal.so") - set(GDAL_INCLUDE_DIR "${GDAL_ROOT}/include") endif() # Path to additional CMake modules @@ -136,14 +138,9 @@ include(ExternalProject-Setup) # Geospatial Data Abstraction Library (GDAL) # set(ODM_GDAL_Version 3.11.1) -if(WIN32) - message(STATUS "GDAL: Using pip-installed version from ${GDAL_ROOT}") - # Create a dummy target to satisfy dependencies - add_custom_target(gdal) -else() - option(ODM_BUILD_GDAL "Force to build GDAL library" ON) - SETUP_EXTERNAL_PROJECT(GDAL ${ODM_GDAL_Version} ${ODM_BUILD_GDAL}) -endif() +option(ODM_BUILD_GDAL "Force to build GDAL library" OFF) + +SETUP_EXTERNAL_PROJECT(GDAL ${ODM_GDAL_Version} ${ODM_BUILD_GDAL}) # --------------------------------------------------------------------------------------------- # Open Source Computer Vision (OpenCV) @@ -243,7 +240,7 @@ externalproject_add(dem2mesh PREFIX ${SB_BINARY_DIR}/dem2mesh SOURCE_DIR ${SB_SOURCE_DIR}/dem2mesh CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} - ${WIN32_GDAL_ARGS} + ${WIN32_CMAKE_ARGS} ${APPLE_CMAKE_ARGS} ) @@ -254,7 +251,7 @@ externalproject_add(dem2points PREFIX ${SB_BINARY_DIR}/dem2points SOURCE_DIR ${SB_SOURCE_DIR}/dem2points CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} - ${WIN32_GDAL_ARGS} + ${WIN32_CMAKE_ARGS} ${APPLE_CMAKE_ARGS} ) @@ -265,7 +262,7 @@ externalproject_add(odm_orthophoto PREFIX ${SB_BINARY_DIR}/odm_orthophoto SOURCE_DIR ${SB_SOURCE_DIR}/odm_orthophoto CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} - ${WIN32_CMAKE_ARGS} ${WIN32_GDAL_ARGS} + ${WIN32_CMAKE_ARGS} ) externalproject_add(fastrasterfilter @@ -275,7 +272,7 @@ externalproject_add(fastrasterfilter PREFIX ${SB_BINARY_DIR}/fastrasterfilter SOURCE_DIR ${SB_SOURCE_DIR}/fastrasterfilter CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} - ${WIN32_CMAKE_ARGS} ${WIN32_GDAL_ARGS} + ${WIN32_CMAKE_ARGS} ) externalproject_add(lastools diff --git a/SuperBuild/cmake/External-GDAL.cmake b/SuperBuild/cmake/External-GDAL.cmake index a5c216eaa..074ff6a6b 100644 --- a/SuperBuild/cmake/External-GDAL.cmake +++ b/SuperBuild/cmake/External-GDAL.cmake @@ -23,7 +23,7 @@ ExternalProject_Add(${_proj_name} BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- INSTALL_DIR ${SB_INSTALL_DIR} - INSTALL_COMMAND "${CMAKE_COMMAND}" --build . --target install + INSTALL_COMMAND "${CMAKE_COMMAND}" --build . --config $ --target install #--Output logging------------- LOG_DOWNLOAD OFF LOG_CONFIGURE OFF diff --git a/SuperBuild/cmake/External-Hexer.cmake b/SuperBuild/cmake/External-Hexer.cmake index c3f1d85e3..c40406633 100644 --- a/SuperBuild/cmake/External-Hexer.cmake +++ b/SuperBuild/cmake/External-Hexer.cmake @@ -8,14 +8,14 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/hobuinc/hexer/archive/5876a5ab1d5b504cf1ea985d66ae359287eef31e.tar.gz + URL https://github.com/hobuinc/hexer/archive/bc226544ca941b6754c343d0e3b42808a3278dec.tar.gz #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} - ${WIN32_GDAL_ARGS} + ${WIN32_CMAKE_ARGS} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- diff --git a/SuperBuild/cmake/External-PDAL.cmake b/SuperBuild/cmake/External-PDAL.cmake index 0a5109544..9a0bfd3fa 100644 --- a/SuperBuild/cmake/External-PDAL.cmake +++ b/SuperBuild/cmake/External-PDAL.cmake @@ -52,7 +52,6 @@ ExternalProject_Add(${_proj_name} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} ${WIN32_CMAKE_ARGS} - ${WIN32_GDAL_ARGS} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- diff --git a/SuperBuild/cmake/External-PDALPython.cmake b/SuperBuild/cmake/External-PDALPython.cmake index f91086864..58bdb079c 100644 --- a/SuperBuild/cmake/External-PDALPython.cmake +++ b/SuperBuild/cmake/External-PDALPython.cmake @@ -33,7 +33,7 @@ ExternalProject_Add(${_proj_name} BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- INSTALL_DIR ${SB_INSTALL_DIR} - INSTALL_COMMAND ${CMAKE_COMMAND} --build --target install + INSTALL_COMMAND ${CMAKE_COMMAND} --build --config $ --target install COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/__init__.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/pipeline.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/drivers.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal diff --git a/SuperBuild/cmake/External-Untwine.cmake b/SuperBuild/cmake/External-Untwine.cmake index b52ea6d63..21ac763fb 100644 --- a/SuperBuild/cmake/External-Untwine.cmake +++ b/SuperBuild/cmake/External-Untwine.cmake @@ -16,7 +16,7 @@ ExternalProject_Add(${_proj_name} SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS -DPDAL_DIR=${SB_INSTALL_DIR}/lib/cmake/PDAL - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} diff --git a/configure.py b/configure.py index 65bb70c24..3446b0664 100644 --- a/configure.py +++ b/configure.py @@ -11,8 +11,10 @@ import os import stat import urllib.request +from urllib.parse import urlparse import shutil import zipfile +import tarfile from venv import EnvBuilder @@ -26,7 +28,7 @@ help='Build VCPKG environment from scratch instead of downloading prebuilt one.') parser.add_argument('--vcpkg-archive-url', type=str, - default='https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/vcpkg-export.zip', + default='https://github.com/OpenDroneMap/windows-deps/releases/download/2.7.0/vcpkg-export.zip', required=False, help='Path to VCPKG export archive') parser.add_argument('--signtool-path', @@ -47,8 +49,7 @@ args = parser.parse_args() -def run(cmd, cwd=os.getcwd()): - env = os.environ.copy() +def run(cmd, cwd=os.getcwd(), env=os.environ.copy()): print(cmd) p = subprocess.Popen(cmd, shell=True, env=env, cwd=cwd) retcode = p.wait() @@ -71,6 +72,31 @@ def vcpkg_requirements(): pckgs = list(filter(lambda l: len(l) > 0, map(str.strip, f.read().split("\n")))) return pckgs +def install_python_package_from_source(url, vcpkg, extractor, get_top_dir): + filename = os.path.basename(urlparse(url).path) + print("Downloading %s --> %s" % (url, filename)) + with urllib.request.urlopen(url) as response, open(os.path.join("SuperBuild", "download", filename), 'wb') as out_file: + shutil.copyfileobj(response, out_file) + + print(f"Extracting {filename}", end="") + top_dir = None + with extractor(os.path.join("SuperBuild", "download", filename)) as z: + top_dir = get_top_dir(z) + z.extractall(os.path.join("SuperBuild", "src")) + + print(f" --> {top_dir}") + src_dir = os.path.join("SuperBuild", "src", top_dir) + + with open(os.path.join(src_dir, "setup.cfg"), "w") as file: + file.write("[build_ext]\n") + file.write("include-dirs = %s\n" % os.path.abspath(os.path.join(vcpkg, "include"))) + file.write("libraries = gdal\n") + file.write("library-dirs = %s\n" % os.path.abspath(os.path.join(vcpkg, "lib"))) + + pip_abs = os.path.abspath(os.path.join("venv", "Scripts", "pip.exe")) + + run(f"\"{pip_abs}\" install .", cwd=src_dir, env={**os.environ, "GDAL_VERSION": "3.11.1"}) + def build(): # Create python virtual env if not os.path.isdir("venv"): @@ -78,8 +104,10 @@ def build(): ebuilder = EnvBuilder(with_pip=True) ebuilder.create("venv") - run("pip install setuptools") - run("venv\\Scripts\\pip install --ignore-installed -r requirements.txt") + run("venv\\Scripts\\pip install setuptools") + + # Install numpy for OpenCV build. TODO: read the exact version from requirements.txt? + run("venv\\Scripts\\pip install numpy==2.3.2") # Download / build VCPKG environment if not os.path.isdir("vcpkg"): @@ -114,9 +142,17 @@ def build(): os.mkdir(build_dir) toolchain_file = os.path.join(os.getcwd(), "vcpkg", "scripts", "buildsystems", "vcpkg.cmake") - run("cmake .. -DCMAKE_TOOLCHAIN_FILE=\"%s\"" % toolchain_file, cwd=build_dir) + run("cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=\"%s\"" % toolchain_file, cwd=build_dir) run("cmake --build . --config Release -j2", cwd=build_dir) + # Build GDAL bindings, fiona and rasterio from source using vcpkg GDAL. TODO: read the exact versions from requirements.txt? + vcpkg_installed = os.path.join(os.getcwd(), "vcpkg", "installed", "x64-windows") + install_python_package_from_source("https://files.pythonhosted.org/packages/source/g/gdal/gdal-3.11.1.tar.gz", vcpkg_installed, lambda path: tarfile.open(path, "r:gz"), lambda t: t.getnames()[0]) + install_python_package_from_source("https://github.com/Toblerity/Fiona/archive/refs/tags/1.10.1.zip", vcpkg_installed, lambda path: zipfile.ZipFile(path), lambda z: z.namelist()[0]) + install_python_package_from_source("https://github.com/rasterio/rasterio/archive/refs/tags/1.4.3.zip", vcpkg_installed, lambda path: zipfile.ZipFile(path), lambda z: z.namelist()[0]) + + run("venv\\Scripts\\pip install -r requirements.txt") + def vcpkg_export(): if not os.path.exists("vcpkg"): print("vcpkg directory does not exist. Did you build the environment?") @@ -168,7 +204,7 @@ def dist(): # Download portable python if not os.path.isdir("python312"): pythonzip_path = os.path.join("SuperBuild", "download", "python312.zip") - python_url = "https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/python-3.12.10-embed-amd64-less-pth.zip" + python_url = "https://github.com/OpenDroneMap/windows-deps/releases/download/2.7.0/python-3.12.9-embed-amd64-less-pth-sqlite.zip" if not os.path.exists(pythonzip_path): print("Downloading %s" % python_url) with urllib.request.urlopen(python_url) as response, open( pythonzip_path, 'wb') as out_file: diff --git a/opendm/cutline.py b/opendm/cutline.py index 692bbebdf..7f715960f 100644 --- a/opendm/cutline.py +++ b/opendm/cutline.py @@ -16,11 +16,6 @@ from shapely.geometry import LineString, mapping, shape from shapely.ops import polygonize, unary_union -if sys.platform == 'win32': - # Temporary fix for: ValueError: GEOSGeom_createLinearRing_r returned a NULL pointer - # https://github.com/Toblerity/Shapely/issues/1005 - shapely.speedups.disable() - def write_raster(data, file): profile = { 'driver': 'GTiff', diff --git a/requirements.txt b/requirements.txt index 2eb06d3f2..65ede7fc9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,7 @@ beautifulsoup4==4.13.4 edt==3.0.0 ExifRead==3.5.1 -Fiona==1.10.1 ; sys_platform == 'linux' -Fiona==1.10.1 ; sys_platform == 'darwin' -https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/fiona-1.10.1-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' +Fiona==1.10.1 numpy==2.3.2 Pillow==11.3.0 pillow-jxl-plugin==1.3.4 @@ -12,10 +10,7 @@ pyodm==1.5.12 pyproj==3.7.1 Pysolar==0.13 PyYAML==6.0.2 -rasterio==1.4.3 ; sys_platform == 'linux' -rasterio==1.4.3 ; sys_platform == 'darwin' -https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/rasterio-1.4.3-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' -https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/gdal-3.11.1-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' +rasterio==1.4.3 scikit-learn==1.7.1 scikit-image==0.25.2 scipy==1.16.1 diff --git a/vcpkg.json b/vcpkg.json index 526ee675b..5d962c6f0 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -25,9 +25,14 @@ "cgal", "yasm-tool", "metis", - "pybind11" + "python3", + "pybind11", + { + "name": "gdal", + "features": ["tools"] + } ], - "builtin-baseline": "6ecbbbdf31cba47aafa7cf6189b1e73e10ac61f8", + "builtin-baseline": "6b68ff33240209010db42256d3f5c3a3c58273fb", "overrides": [ { "name": "eigen3", "version": "3.4.0#5" }, { "name": "suitesparse", "version": "5.8.0" }, @@ -41,19 +46,21 @@ { "name": "libjpeg-turbo", "version": "3.1.1" }, { "name": "tiff", "version": "4.7.0" }, { "name": "flann", "version": "2022-10-28" }, - { "name": "boost-filesystem", "version": "1.88.0" }, - { "name": "boost-date-time", "version": "1.88.0" }, - { "name": "boost-iostreams", "version": "1.88.0" }, - { "name": "boost-foreach", "version": "1.88.0" }, - { "name": "boost-signals2", "version": "1.88.0" }, - { "name": "boost-interprocess", "version": "1.88.0" }, - { "name": "boost-graph", "version": "1.88.0" }, - { "name": "boost-asio", "version": "1.88.0" }, - { "name": "boost-program-options", "version": "1.88.0" }, + { "name": "boost-filesystem", "version": "1.90.0" }, + { "name": "boost-date-time", "version": "1.90.0" }, + { "name": "boost-iostreams", "version": "1.90.0" }, + { "name": "boost-foreach", "version": "1.90.0" }, + { "name": "boost-signals2", "version": "1.90.0" }, + { "name": "boost-interprocess", "version": "1.90.0" }, + { "name": "boost-graph", "version": "1.90.0" }, + { "name": "boost-asio", "version": "1.90.0" }, + { "name": "boost-program-options", "version": "1.90.0" }, { "name": "libgeotiff", "version": "1.7.4" }, { "name": "cgal", "version": "6.0.1" }, { "name": "yasm-tool", "version": "2021-12-14" }, { "name": "metis", "version": "2025-07-04" }, - { "name": "pybind11", "version": "3.0.0#1" } + { "name": "python3", "version": "3.12.9#9" }, + { "name": "pybind11", "version": "3.0.0#1" }, + { "name": "gdal", "version": "3.11.1" } ] } \ No newline at end of file diff --git a/win32env.bat b/win32env.bat index a73f63d55..59b2b9efe 100644 --- a/win32env.bat +++ b/win32env.bat @@ -9,15 +9,15 @@ if defined _OLD_CODEPAGE ( ) set ODMBASE=%~dp0 -set GDALBASE=%ODMBASE%venv\Lib\site-packages\osgeo +set GDALBASE=%ODMBASE%SuperBuild\install\bin set GDAL_DATA=%GDALBASE%\data\gdal set GDAL_DRIVER_PATH=%GDALBASE%\gdalplugins set OSFMBASE=%ODMBASE%SuperBuild\install\bin\opensfm\bin set SBBIN=%ODMBASE%SuperBuild\install\bin set PDAL_DRIVER_PATH=%ODMBASE%SuperBuild\install\bin -set PYTHONPYCACHEPREFIX=%PROGRAMDATA%\ODM\pycache +if not defined ODMDONTSETPYCACHE set PYTHONPYCACHEPREFIX=%PROGRAMDATA%\ODM\pycache -set PATH=%GDALBASE%;%SBBIN%;%OSFMBASE% +set PATH=%SBBIN%;%OSFMBASE% set PROJ_LIB=%GDALBASE%\data\proj set VIRTUAL_ENV=%ODMBASE%venv