Installing GDAL on Windows with rgeowheels
Source:vignettes/installing-gdal-windows.Rmd
installing-gdal-windows.RmdOverview
Installing geospatial Python packages on Windows can be challenging due to complex binary dependencies and the need for pre-compiled wheels. The rgeowheels package dramatically simplifies this process by providing convenient access to Christoph Gohlke’s curated collection of pre-compiled geospatial wheels, especially for GDAL and related libraries.
Note: This vignette demonstrates Windows-specific workflows. The code examples will only execute successfully on Windows systems, as rgeowheels provides pre-compiled wheels specifically for Windows architectures (win32, win_amd64, win_arm64).
This vignette demonstrates how to:
- Create and activate a virtual environment for Python development
- Detect available Python versions in your environment
- Use rgeowheels to install geospatial wheels (like GDAL) into that environment
- Verify the installation works with reticulate
This workflow is particularly useful for:
- Continuous Integration (CI) workflows where you need reproducible Python environments
- Reticulate-based R packages that require specific geospatial dependencies
- Development workflows where you want isolated Python environments per project
Getting Started: Creating a Virtual Environment
The recommended approach is to create a dedicated Python virtual environment for your project. This isolates your project dependencies from system Python and other projects.
Using reticulate to Create a Venv
If you already have Python installed, you can create a virtual environment directly in R using reticulate:
library(reticulate)
# Create a virtual environment in your project directory
venv_path <- file.path(getwd(), ".venv")
virtualenv_create(venv_path, python = Sys.which("python"))
# Activate the virtual environment
use_virtualenv(venv_path, required = TRUE)Alternatively, create the venv from the command line:
Detecting Available Python Versions
Before installing wheels, it’s helpful to understand what Python
environments are available. The detect_python_envs()
function scans your system for virtual environments and conda
environments:
library(rgeowheels)
#> rgeowheels 0.1.0
#> - Cached release asset list not found, run `list_rgeowheels_assets()` to begin.
# Discover available Python environments
envs <- detect_python_envs()
envs
#> type path version
#> python system C:\\HOSTED~1\\windows\\Python\\314~1.0\\x64\\python.exe 3.14
#> active
#> python TRUEYou can also check the Python version of a specific environment:
# Get the version of the currently active Python
current_version <- detect_python_version()
current_version
# Or check a specific Python binary (wrapped in try to handle venv if not present)
venv_python <- file.path(".venv", "Scripts", "python.exe") # Windows
if (file.exists(venv_python)) {
venv_version <- detect_python_version(venv_python)
venv_version
}Installing GDAL via rgeowheels
Once you have a Python environment set up and activated, installing GDAL is straightforward:
Basic Installation (Auto-Detect Python Version)
The simplest approach is to use pyversion = "auto" to
automatically detect your Python version and match it to available
wheels:
library(rgeowheels)
library(reticulate)
# Ensure your virtual environment is active
use_virtualenv(".venv", required = TRUE)
# Install GDAL - automatically detects Python version
install_wheel("GDAL", version = "latest", pyversion = "auto")This will:
- Detect your active Python version (e.g., “3.11”)
- Display a message:
"Auto-selected Python 3.11 for GDAL" - Find and download the matching GDAL wheel
- Install it via
pip
Suppressing the Auto-Detect Message
If you want to use auto-detection but suppress the informational message (useful in scripts or CI), you have three options:
Option 1: Set an environment variable
Sys.setenv(R_RGEOWHEELS_QUIET_AUTO = "TRUE")
install_wheel("GDAL", pyversion = "auto")Option 2: Set an R option
options(rgeowheels.quiet_auto = TRUE)
install_wheel("GDAL", pyversion = "auto")Option 3: Explicitly specify the Python version
# Once you know the version, you can pin it explicitly (message is suppressed)
install_wheel("GDAL", pyversion = "3.11")Explicit Version Specification
If you need a specific version of GDAL for a specific Python version:
install_wheel(
package = "GDAL",
version = "3.8.4", # Specific GDAL version
pyversion = "3.11", # Specific Python version
architecture = "win_amd64" # Windows 64-bit (default)
)Check Available Versions
Before installing, you can see what versions are available:
# List all available wheels
assets <- list_rgeowheels_assets()
# Filter for GDAL
gdal_wheels <- assets[assets$package == "GDAL", ]
print(gdal_wheels[, c("package", "version", "pyversion", "architecture")])
#> package version pyversion architecture
#> 478 GDAL 3.10.1 3.10 win32
#> 479 GDAL 3.10.1 3.10 win_amd64
#> 480 GDAL 3.10.1 3.11 win32
#> 481 GDAL 3.10.1 3.11 win_amd64
#> 482 GDAL 3.10.1 3.11 win_arm64
#> 483 GDAL 3.10.1 3.12 win32
#> 484 GDAL 3.10.1 3.12 win_amd64
#> 485 GDAL 3.10.1 3.12 win_arm64
#> 486 GDAL 3.10.1 3.13 win32
#> 487 GDAL 3.10.1 3.13 win_amd64
#> 488 GDAL 3.10.1 3.13 win_arm64
#> 489 GDAL 3.10.1 3.10 win_amd64
#> 617 GDAL 3.9.2 3.10 win32
#> 618 GDAL 3.9.2 3.10 win_amd64
#> 619 GDAL 3.9.2 3.11 win32
#> 620 GDAL 3.9.2 3.11 win_amd64
#> 621 GDAL 3.9.2 3.11 win_arm64
#> 622 GDAL 3.9.2 3.12 win32
#> 623 GDAL 3.9.2 3.12 win_amd64
#> 624 GDAL 3.9.2 3.12 win_arm64
#> 625 GDAL 3.9.2 3.13 win32
#> 626 GDAL 3.9.2 3.13 win_amd64
#> 627 GDAL 3.9.2 3.13 win_arm64
#> 628 GDAL 3.9.2 3.9 win32
#> 629 GDAL 3.9.2 3.9 win_amd64
#> 630 GDAL 3.9.2 3.10 win_amd64
#> 759 GDAL 3.8.4 3.10 win32
#> 760 GDAL 3.8.4 3.10 win_amd64
#> 761 GDAL 3.8.4 3.11 win32
#> 762 GDAL 3.8.4 3.11 win_amd64
#> 763 GDAL 3.8.4 3.11 win_arm64
#> 764 GDAL 3.8.4 3.12 win32
#> 765 GDAL 3.8.4 3.12 win_amd64
#> 766 GDAL 3.8.4 3.12 win_arm64
#> 767 GDAL 3.8.4 3.9 win32
#> 768 GDAL 3.8.4 3.9 win_amd64
#> 769 GDAL 3.8.4 3.10 win_amd64
#> 880 GDAL 3.8.2 3.10 win32
#> 881 GDAL 3.8.2 3.10 win_amd64
#> 882 GDAL 3.8.2 3.11 win32
#> 883 GDAL 3.8.2 3.11 win_amd64
#> 884 GDAL 3.8.2 3.11 win_arm64
#> 885 GDAL 3.8.2 3.12 win32
#> 886 GDAL 3.8.2 3.12 win_amd64
#> 887 GDAL 3.8.2 3.12 win_arm64
#> 888 GDAL 3.8.2 3.9 win32
#> 889 GDAL 3.8.2 3.9 win_amd64
#> 890 GDAL 3.8.2 3.10 win_amd64
#> 1001 GDAL 3.7.3 3.10 win32
#> 1002 GDAL 3.7.3 3.10 win_amd64
#> 1003 GDAL 3.7.3 3.11 win32
#> 1004 GDAL 3.7.3 3.11 win_amd64
#> 1005 GDAL 3.7.3 3.11 win_arm64
#> 1006 GDAL 3.7.3 3.12 win32
#> 1007 GDAL 3.7.3 3.12 win_amd64
#> 1008 GDAL 3.7.3 3.12 win_arm64
#> 1009 GDAL 3.7.3 3.9 win32
#> 1010 GDAL 3.7.3 3.9 win_amd64
#> 1011 GDAL 3.7.3 3.10 win_amd64
#> 1122 GDAL 3.7.2 3.10 win32
#> 1123 GDAL 3.7.2 3.10 win_amd64
#> 1124 GDAL 3.7.2 3.11 win32
#> 1125 GDAL 3.7.2 3.11 win_amd64
#> 1126 GDAL 3.7.2 3.11 win_arm64
#> 1127 GDAL 3.7.2 3.12 win32
#> 1128 GDAL 3.7.2 3.12 win_amd64
#> 1129 GDAL 3.7.2 3.12 win_arm64
#> 1130 GDAL 3.7.2 3.9 win32
#> 1131 GDAL 3.7.2 3.9 win_amd64
#> 1132 GDAL 3.7.2 3.10 win_amd64
#> 1243 GDAL 3.7.1 3.10 win32
#> 1244 GDAL 3.7.1 3.10 win_amd64
#> 1245 GDAL 3.7.1 3.11 win32
#> 1246 GDAL 3.7.1 3.11 win_amd64
#> 1247 GDAL 3.7.1 3.11 win_arm64
#> 1248 GDAL 3.7.1 3.12 win32
#> 1249 GDAL 3.7.1 3.12 win_amd64
#> 1250 GDAL 3.7.1 3.12 win_arm64
#> 1251 GDAL 3.7.1 3.9 win32
#> 1252 GDAL 3.7.1 3.9 win_amd64
#> 1253 GDAL 3.7.1 3.10 win_amd64
# Or with a specific Python version
gdal_py311 <- assets[assets$package == "GDAL" & assets$pyversion == "3.11", ]Complete Workflow Example: CI/CD Integration with Reticulate
Here’s a complete workflow combining reticulate venv creation with rgeowheels installation:
library(reticulate)
library(rgeowheels)
# 1. Create a virtual environment
venv_path <- file.path(getwd(), ".venv")
if (!dir.exists(venv_path)) {
virtualenv_create(venv_path, python = Sys.which("python"))
}
# 2. Activate it
use_virtualenv(venv_path, required = TRUE)
# 3. Detect available Python in this venv
detect_python_envs()
# 4. Install geospatial wheels
install_wheel("GDAL", version = "latest", pyversion = "auto")
install_wheel("rasterio", version = "latest", pyversion = "auto")
install_wheel("fiona", version = "latest", pyversion = "auto")
# 5. Verify installations
py_run_string("from osgeo import gdal; print(f'GDAL {gdal.__version__}')")
py_run_string("import rasterio; print(f'Rasterio {rasterio.__version__}')")
# 6. Use Python objects in R
py_run_string("
import rasterio
from rasterio.plot import show
# ... your geospatial Python code here
")Troubleshooting
“Could not find wheels for…” Error
If you see an error like:
could not find wheels for:
- 'GDAL' version 'latest' for Python '3.9' (win_amd64)
Available Python versions for 'GDAL' (win_amd64): 3.10, 3.11, 3.12
This means GDAL wheels aren’t available for Python 3.9. You have two options:
- Update Python: Upgrade to a supported version (3.10, 3.11, or 3.12)
- Explicit version: Specify an available Python version
# Upgrade your venv to Python 3.11
virtualenv_create(".venv_311", python = "C:/Python311/python.exe")
use_virtualenv(".venv_311")
# Or explicitly request 3.11
install_wheel("GDAL", pyversion = "3.11")Python Binary Not Found
If detect_python_version() fails with “Python binary not
found”, ensure:
- Python is installed and in your PATH:
Sys.which("python") - Your virtual environment is activated:
use_virtualenv(".venv") - You’ve set the Python path explicitly:
set_rgeowheels_python("C:/path/to/venv/Scripts/python.exe")
detect_python_version()Setting Custom Python Path
If you have multiple Python installations, you can explicitly set which one rgeowheels uses:
# Set for this session
set_rgeowheels_python("C:/Python311/python.exe")
# Or via environment variable (persists across R sessions)
Sys.setenv(R_RGEOWHEELS_PYTHON = "C:/Python311/python.exe")CI/CD Integration Examples
GitHub Actions Workflow
Here’s a sample abbreviated YAML configuration for using rgeowheels in GitHub Actions CI:
name: Test with GDAL
on: [push, pull_request]
jobs:
test:
runs-on: windows-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
r-version: ['4.2', '4.3']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.r-version }}
- name: Install R packages
run: |
install.packages(c("reticulate", "rgeowheels"))
shell: Rscript {0}
- name: Install Python geospatial wheels
run: |
library(rgeowheels)
library(reticulate)
use_python(Sys.which("python"))
install_wheel("GDAL", pyversion = "auto")
install_wheel("rasterio", pyversion = "auto")
shell: Rscript {0}
- name: Run tests
run: |
Rscript -e 'tinytest::test_all()'Performance Benefits
The rgeowheels workflow provides significant advantages on Windows:
- Speed: Pre-compiled wheels install in seconds (vs. compilation time)
- Reliability: No compiler requirements or build failures
- Reproducibility: Exact versions specified and matched consistently
-
Simplicity: One-line installation via
install_wheel() - CI/CD-friendly: Works seamlessly in headless environments
Summary
By combining rgeowheels with reticulate’s virtual environment management, you can create reproducible, isolated Python development environments on Windows with geospatial dependencies installed in seconds. This is especially valuable for:
- Complex R packages that bridge to geospatial Python libraries
- Data science workflows requiring both R and Python geospatial tools
- CI/CD pipelines where consistent environments are critical
- Teams working on Windows systems without compiler infrastructure
For more information, see ?install_wheel,
?detect_python_version, and
?detect_python_envs.