Skip to content

Add Urban Heat Island mapping notebook with MODIS LST - #1343

Merged
giswqs merged 6 commits into
opengeos:masterfrom
Qandeel-01:add-urban-heat-island-notebook
Aug 2, 2026
Merged

Add Urban Heat Island mapping notebook with MODIS LST#1343
giswqs merged 6 commits into
opengeos:masterfrom
Qandeel-01:add-urban-heat-island-notebook

Conversation

@Qandeel-01

@Qandeel-01 Qandeel-01 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Adds docs/notebooks/117_urban_heat_island.ipynb — an end-to-end notebook for visualizing Urban Heat Island (UHI) effects using MODIS MOD11A2 Land Surface Temperature data and leafmap.

What this notebook covers

  • Searching and downloading MODIS MOD11A2 (8-day LST, 1 km) via earthaccess
  • Applying scale factor (×0.02) and Kelvin→Celsius conversion with rioxarray
  • Rendering LST on an interactive leafmap with a diverging colormap and colorbar
  • Building a split map to compare LST against satellite and street basemaps
  • Computing a simple Urban Heat Island intensity index (pixel LST − scene mean)

Study area

Lahore, Pakistan — a South Asian megacity with well-documented UHI intensity, using a June 2023 summer granule to capture peak thermal contrast between built-up and vegetated land.

Motivation

No UHI or thermal LST example currently exists in the docs (notebooks 00–116). This fills that gap with a workflow directly applicable to climate research, urban planning, and heat risk assessment.

Related notebooks

  • 116_hls_nasa_earthdata.ipynb — NASA Earthdata access (same earthaccess pattern)
  • 05_load_raster.ipynb — raster loading
  • 12_split_map.ipynb — split map widget

Summary by CodeRabbit

  • Documentation
    • Added a complete Jupyter notebook demonstrating Urban Heat Island analysis for Lahore, Pakistan.
    • Shows how to retrieve and process MODIS land surface temperature data, apply quality filtering, and convert temperatures to Celsius.
    • Includes static and interactive visualizations, satellite comparisons, and split-map views.
    • Computes, exports, and visualizes land surface temperature and Urban Heat Island results.
    • Added the notebook to the documentation navigation.

Demonstrates querying MODIS MOD11A2 LST via earthaccess, applying
scale factors with rioxarray, and visualizing Urban Heat Island
intensity interactively with leafmap split maps and colorbars.
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Added a Jupyter notebook that demonstrates MODIS MOD11A2 LST acquisition, preprocessing, GeoTIFF export, interactive mapping, split-map comparison, and scene-mean UHI index visualization for Lahore.

Changes

Urban Heat Island Workflow

Layer / File(s) Summary
Data acquisition and LST processing
docs/notebooks/117_urban_heat_island.ipynb
Authenticates with NASA Earthdata, searches and downloads a June 2023 Lahore MODIS granule, clips LST and QC layers, masks invalid pixels, and converts daytime LST values to Celsius.
LST visualization and export
docs/notebooks/117_urban_heat_island.ipynb
Plots and exports the processed LST raster, displays it with leafmap, and provides a satellite/OpenStreetMap split-map comparison.
UHI index, visualization, and navigation
docs/notebooks/117_urban_heat_island.ipynb, zensical.toml
Computes, exports, and visualizes the scene-mean UHI index. Adds workflow references, notebook metadata, and the notebook to the documentation navigation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Notebook
  participant Earthaccess
  participant MODIS
  participant Leafmap
  Notebook->>Earthaccess: Authenticate and search June 2023 Lahore granules
  Earthaccess->>MODIS: Download first matching MOD11A2 granule
  MODIS-->>Notebook: Provide HDF granule source
  Notebook->>Notebook: Clip, mask, and convert LST to Celsius
  Notebook->>Notebook: Compute scene-mean UHI index
  Notebook->>Leafmap: Render LST and UHI GeoTIFF overlays
Loading

Poem

I’m a rabbit hopping through pixels of heat,
Lahore glows beneath my quick little feet.
MODIS brings warmth, maps bloom bright,
GeoTIFFs capture the summer light.
UHI hops where hot spots meet!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the new Urban Heat Island mapping notebook and its use of MODIS LST data.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mergify

mergify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/notebooks/117_urban_heat_island.ipynb`:
- Around line 143-151: Update the notebook’s daytime LST processing around
lst_raw to load the QC_Day subdataset, decode bits 0–1, and mask lst_raw to
retain only good-quality daytime pixels before applying the 0.02 scale factor or
computing lst_celsius, scene means, and UHI. Preserve the existing fill-value
masking while ensuring all downstream calculations use the quality-filtered LST.
- Around line 143-151: Clip lst_raw to bbox immediately after loading and
squeezing it, before applying the scale factor; ensure the resulting
Lahore-specific lst_celsius is used for export and scene_mean aggregation.
- Around line 258-271: Update the split-map setup around m2.split_map to use
lst_output as one pane instead of adding it afterward with m2.add_raster. Keep
the satellite basemap as the opposite pane and preserve the existing LST
colormap, layer name, and opacity settings when configuring the raster side.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f1308c9a-3d3b-446f-9f68-4f07e1c03676

📥 Commits

Reviewing files that changed from the base of the PR and between 4785fc0 and f6bf5a9.

📒 Files selected for processing (1)
  • docs/notebooks/117_urban_heat_island.ipynb

Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
@giswqs

giswqs commented Jul 18, 2026

Copy link
Copy Markdown
Member

/claude-review

Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
@github-actions

Copy link
Copy Markdown

Code review

This PR adds a new documentation notebook (docs/notebooks/117_urban_heat_island.ipynb) demonstrating an Urban Heat Island workflow with MODIS MOD11A2 LST data. No library code is touched — review focused on whether the notebook's leafmap API calls are correct and will execute successfully.

Bugs

  • add_colorbar(cmap=..., label=..., ...) uses non-existent parameters (high confidence). add_colorbar's real signature is add_colorbar(colors, vmin=0, vmax=1.0, ..., caption="", ...)colors is a required positional list of hex/RGB colors, and there is no cmap or label kwarg. Both calls (for m and m3) will raise TypeError: add_colorbar() missing 1 required positional argument: 'colors'. Every other notebook in the repo uses add_colorbar(colors=colors, vmin=vmin, vmax=vmax).
  • leafmap.basemap_to_tiles does not exist (high confidence). It isn't defined anywhere in the leafmap package. The split-map cell will raise AttributeError. The repo's own convention (12_split_map.ipynb) is to pass basemap name strings directly to split_map(left_layer=..., right_layer=...).
  • Split map doesn't compare LST vs. satellite as described (medium confidence). m2.add_raster(...) is called after split_map(...) and just overlays the LST raster on top of both panes equally, rather than placing it into one side of the split control — contradicting the markdown's claim that the widget lets users "swipe between the LST layer and the satellite basemap."
  • Unchecked empty results (low-medium confidence). results[0] and files[0] are indexed without verifying the list is non-empty; an empty search result (plausible given the fixed month/bbox) would raise an unhandled IndexError right after printing "Found 0 granule(s)".

Security

  • None found. No credentials, secrets, or unsafe input handling — earthaccess.login() uses the standard NASA Earthdata auth flow with local ~/.netrc storage, consistent with the existing 116_hls_nasa_earthdata.ipynb notebook.

Performance

  • None found. This is a documentation notebook operating on a single small raster; no obvious inefficiencies.

Quality

  • Given the two confirmed API-usage bugs above, the notebook has very likely not been executed end-to-end before submission — worth re-running top-to-bottom to catch these before merge.
  • Minor: rxr.open_rasterio(..., masked=True) already applies nodata masking from file metadata, and the code additionally does .where(lst_raw != 0) — not wrong (MOD11A2's fill value is 0), but a short comment on why both are needed would help readability (low confidence nit).

CLAUDE.md

  • No CLAUDE.md file exists in this repository, so no project-specific guidelines apply.

Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
- add_colorbar: replace non-existent cmap/label/position kwargs with
  correct colors/vmin/vmax signature
- split_map: remove leafmap.basemap_to_tiles() which does not exist;
  use string basemap names directly
- Search/download: add guards against empty results and files lists
@Qandeel-01

Copy link
Copy Markdown
Contributor Author

Fixed all issues from the automated code review:

  • add_colorbar: Replaced cmap/label/position with the correct colors/vmin/vmax signature (matching the 07_colorbar.ipynb convention). Used hex color lists for RdYlBu_r and seismic colormaps.
  • leafmap.basemap_to_tiles: Removed the non-existent function call; now passes basemap name strings ("SATELLITE", "OpenStreetMap") directly to split_map, matching the 12_split_map.ipynb convention.
  • Empty-list guards: Added if not results and if not files checks with descriptive ValueError messages before indexing.
  • Split map description: Updated the markdown to accurately describe what the split map shows (satellite vs. OpenStreetMap with LST overlay on both sides).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/notebooks/117_urban_heat_island.ipynb (2)

40-40: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Install leafmap’s raster extra.

This notebook installs bare leafmap but later calls Map.add_raster on local GeoTIFFs, so the raster dependencies (including localtileserver) should be installed with leafmap[raster].

Proposed fix
-    "# %pip install leafmap earthaccess rioxarray matplotlib numpy"
+    "# %pip install \"leafmap[raster]\" earthaccess rioxarray matplotlib numpy"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` at line 40, Update the notebook’s
dependency installation line to install the raster extra for leafmap, using
`leafmap[raster]` instead of bare `leafmap`; preserve the other packages
unchanged.

Source: MCP tools


199-204: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the raster colormap bounds aligned with the colorbar bounds.

add_raster and add_colorbar each accept vmin/vmax, so the LST raster can render values outside the legend’s 20–50 range and the UHI raster outside –5–5. Pass the same bounds to both calls for each raster.

Proposed fix
 m.add_raster(
     lst_output,
     colormap="RdYlBu_r",
+    vmin=20,
+    vmax=50,
     layer_name="LST Day (°C)",
     opacity=0.75,
 )

 m3.add_raster(
     uhi_output,
     colormap="seismic",
+    vmin=-5,
+    vmax=5,
     layer_name="UHI Index (°C above mean)",
     opacity=0.75,
 )

Also applies to lines 251-256.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` around lines 199 - 204, Update
the raster display calls in the notebook to pass explicit vmin/vmax bounds
matching their corresponding colorbars: use 20–50 for the LST layer around
add_raster and add_colorbar, and –5–5 for the UHI layer. Apply this consistently
to the second raster section as well.

Source: MCP tools

♻️ Duplicate comments (2)
docs/notebooks/117_urban_heat_island.ipynb (2)

126-140: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Clip the granule to Lahore before deriving outputs.

bounding_box only limits discovery; lst_raw remains the full MODIS tile, so the exported rasters and scene_mean include areas outside Lahore. Clip the LST and QC arrays before scaling, using the bbox CRS explicitly, e.g. rio.clip_box(*bbox, crs="EPSG:4326"). (corteva.github.io)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` around lines 126 - 140, Clip
lst_raw and the corresponding QC array to the Lahore bounding box using
rio.clip_box with crs="EPSG:4326" before scaling or deriving outputs. Ensure the
clipped arrays, rather than the full MODIS tile, feed lst_celsius, exported
rasters, and scene_mean.

Source: MCP tools


126-134: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Mask QC_Day before calculating LST and UHI.

where(lst_raw != 0) only removes fill values. MOD11A2 uses QC_Day bits 0–1 to distinguish good retrievals from other-quality, cloud-affected, and unavailable pixels; those unfiltered pixels currently feed every downstream calculation. Retain only (qc.astype("uint8") & 0b11) == 0 before applying the scale factor. (ladsweb.modaps.eosdis.nasa.gov)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` around lines 126 - 134, Update
the daytime LST preparation near lst_raw to load the QC_Day subdataset, retain
only pixels where QC_Day bits 0–1 equal zero using the specified uint8 mask, and
combine that mask with the existing fill-value filtering before applying the
0.02 scale factor and Celsius conversion. Ensure the filtered lst_celsius
continues feeding downstream UHI calculations.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/notebooks/117_urban_heat_island.ipynb`:
- Line 40: Update the notebook’s dependency installation line to install the
raster extra for leafmap, using `leafmap[raster]` instead of bare `leafmap`;
preserve the other packages unchanged.
- Around line 199-204: Update the raster display calls in the notebook to pass
explicit vmin/vmax bounds matching their corresponding colorbars: use 20–50 for
the LST layer around add_raster and add_colorbar, and –5–5 for the UHI layer.
Apply this consistently to the second raster section as well.

---

Duplicate comments:
In `@docs/notebooks/117_urban_heat_island.ipynb`:
- Around line 126-140: Clip lst_raw and the corresponding QC array to the Lahore
bounding box using rio.clip_box with crs="EPSG:4326" before scaling or deriving
outputs. Ensure the clipped arrays, rather than the full MODIS tile, feed
lst_celsius, exported rasters, and scene_mean.
- Around line 126-134: Update the daytime LST preparation near lst_raw to load
the QC_Day subdataset, retain only pixels where QC_Day bits 0–1 equal zero using
the specified uint8 mask, and combine that mask with the existing fill-value
filtering before applying the 0.02 scale factor and Celsius conversion. Ensure
the filtered lst_celsius continues feeding downstream UHI calculations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 50486b87-f4ed-4a6d-8e77-be2117ff7fe5

📥 Commits

Reviewing files that changed from the base of the PR and between f6bf5a9 and f76c42c.

📒 Files selected for processing (1)
  • docs/notebooks/117_urban_heat_island.ipynb

@giswqs

giswqs commented Aug 2, 2026

Copy link
Copy Markdown
Member

/claude-review

Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
Comment thread docs/notebooks/117_urban_heat_island.ipynb Outdated
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

All four inline comments posted successfully. Now for the HDF4 GDAL dependency note — I'll fold that into the summary as a lower-confidence practical concern rather than an inline comment, since it's about environment/dependency fragility rather than a specific line-level defect.

Code review

This PR adds a single new documentation notebook (docs/notebooks/117_urban_heat_island.ipynb, 296 lines, no source code changes). Notebooks in this repo are not executed in CI (scripts/convert_notebooks.py only converts stored cells to Markdown), so the API usage was checked against the current leafmap source and sibling notebooks rather than by execution.

Bugs

  • None found with high confidence. One low-medium-confidence edge case: hdf_path = files[0] (line 109) assumes the first file earthaccess.download() returns is the .hdf data granule; if a metadata/browse sidecar is returned first, the later HDF4_EOS open call would fail. Worth filtering by extension explicitly.

Security

  • None found. No credentials, injection vectors, or unsafe input handling — the notebook only calls earthaccess/rioxarray/leafmap APIs with static, hardcoded parameters.

Performance

  • None found; this is a linear, single-execution documentation workflow with no obvious inefficiencies.

Quality

  • add_raster() is called without vmin/vmax for both the LST map and the UHI map, while the accompanying add_colorbar() calls hardcode vmin=20, vmax=50 and vmin=-5, vmax=5 respectively. Since add_raster auto-stretches from raster statistics when no vmin/vmax is given, the rendered colors likely won't match the colorbar legend. The repo's established pattern (e.g. 115_terrascope.ipynb) is to pass matching vmin/vmax to both calls. Confidence: medium (2 inline comments).
  • import numpy as np is unused throughout the notebook. Confidence: high (1 inline comment).
  • Lower-confidence, non-blocking note not filed inline: opening the MOD11A2 subdataset via the HDF4_EOS:EOS_GRID:... GDAL driver string requires HDF4 support in the user's GDAL build, which is commonly missing from default pip-installed rasterio/rioxarray wheels. This is inherent to the MODIS HDF4 format rather than a bug in the PR, but could trip up readers following the %pip install rioxarray instructions verbatim.
  • Minor, not filed inline: the PR description states this notebook follows "the same earthaccess pattern" as 116_hls_nasa_earthdata.ipynb, but 116 uses the leafmap.nasa_data_login/search/download wrapper functions while 117 calls earthaccess directly — a stylistic inconsistency, not a defect. The notebook also omits the JupyterLite/Binder badges present in sibling notebooks 115/116 (Colab badge only).

CLAUDE.md

  • No CLAUDE.md guidance applicable to notebook content was found in this repository.

- Clip the MOD11A2 granule to the Lahore bbox before scaling, exporting,
  and averaging. The granule covers a full ~1200 km MODIS tile, so the
  exported rasters and the UHI scene mean were not Lahore-specific.
- Mask low-quality pixels using the QC_Day mandatory QA flags (bits 0-1),
  so cloud-contaminated retrievals no longer feed into the LST or the
  UHI index.
- Split map now uses the LST raster as the left pane against the
  satellite basemap, matching the section's stated intent, instead of
  overlaying it on top of both panes.
- Pass matching vmin/vmax to add_raster in the LST and UHI maps so the
  rendered stretch lines up with the hardcoded colorbar ranges.
- Select the downloaded .hdf explicitly instead of files[0]; earthaccess
  can return sidecar files in unspecified order.
- Drop the unused numpy import (and the matching pip install entry).
- Register the notebook in the Zensical docs nav.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/notebooks/117_urban_heat_island.ipynb (1)

149-155: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fail fast when the QA mask removes every pixel.

If no pixel passes good_quality, lst_celsius.min(), lst_celsius.mean(), and the subsequent rio.to_raster() calls operate on an all-NaN array. Xarray reductions skip NaNs, so this case does not raise automatically. Count valid pixels after the mask and raise a descriptive ValueError before exporting.

Proposed validation
 lst_kelvin = lst_raw.where((lst_raw != 0) & good_quality) * 0.02
 lst_celsius = lst_kelvin - 273.15
+valid_pixels = int(lst_celsius.count().item())
+if valid_pixels == 0:
+    raise ValueError("No valid LST pixels remain after applying the QC_Day mask.")
 
 print(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` around lines 149 - 155, Add
validation after computing lst_celsius and before the range output or any
rio.to_raster calls: count non-NaN pixels remaining after the good_quality mask,
and raise a descriptive ValueError when the count is zero. Preserve the existing
reductions and raster export behavior when at least one valid pixel remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/notebooks/117_urban_heat_island.ipynb`:
- Line 40: Update the notebook’s commented dependency-install command to use the
raster-enabled leafmap extra (`leafmap[raster]`) instead of bare `leafmap`, and
ensure the setup documents or provisions GDAL with HDF4 support for
`rxr.open_rasterio` before the local raster cells use `m.add_raster` and
`m.split_map`.

---

Outside diff comments:
In `@docs/notebooks/117_urban_heat_island.ipynb`:
- Around line 149-155: Add validation after computing lst_celsius and before the
range output or any rio.to_raster calls: count non-NaN pixels remaining after
the good_quality mask, and raise a descriptive ValueError when the count is
zero. Preserve the existing reductions and raster export behavior when at least
one valid pixel remains.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e9205e4e-8b31-43a8-a5bb-6a77b7f857fd

📥 Commits

Reviewing files that changed from the base of the PR and between f76c42c and c9db89e.

📒 Files selected for processing (2)
  • docs/notebooks/117_urban_heat_island.ipynb
  • zensical.toml

"metadata": {},
"outputs": [],
"source": [
"# %pip install leafmap earthaccess rioxarray matplotlib"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Repository files matching notebook:\n'
fd -a '117_urban_heat_island.ipynb' . || true

printf '\nOutline/stat for notebook:\n'
if [ -f docs/notebooks/117_urban_heat_island.ipynb ]; then
  wc -l docs/notebooks/117_urban_heat_island.ipynb
  python3 - <<'PY'
import json, pathlib
p=pathlib.Path('docs/notebooks/117_urban_heat_island.ipynb')
nb=json.loads(p.read_text())
for i, cell in enumerate(nb['cells'],1):
    source=''.join(cell.get('source',[]))[:2000]
    if any(k in source for k in ['%pip install','add_raster','split_map','open_rasterio','earthaccess','leafmap','leafmap']):
        print(f'\nCell {i} type={cell["cell_type"]}')
        lines=source.splitlines()
        for j,l in enumerate(lines):
            if any(s in l for s in ['%pip install','add_raster','split_map','open_rasterio','rxr.open_rasterio','earthaccess','leafmap']):
                print(f'{j+1}: {l}')
PY
fi

printf '\nSearch relevant symbols in docs/notebooks:\n'
rg -n --glob '*.ipynb' 'add_raster|split_map|open_rasterio|rxr\.open_rasterio|%pip install|leafmap\[raster\]|localtileserver|earthaccess|rioxarray' docs/notebooks || true

printf '\nCheck installed package metadata availability if present:\n'
python3 - <<'PY'
import importlib.util, importlib.metadata, sys
for name in ['leafmap','localtileserver','rasterio','rioxarray']:
    spec=importlib.util.find_spec(name)
    print(f"{name}: spec={bool(spec)}", end='')
    if spec:
        print(f" origin={spec.origin}")
        try:
            md=importlib.metadata.metadata(name)
        except importlib.metadata.PackageNotFoundError as e:
            md=None
            print(f" metadata_missing={e}")
        else:
            print(f" requires_dist={md.get('Requires-Dist','')}")
    else:
        print()
PY

Repository: opengeos/leafmap

Length of output: 18671


🌐 Web query:

leafmap raster extra localtileserver rioxarray GDAL HDF4 driver pip wheels

💡 Result:

Leafmap, localtileserver, and rioxarray are common tools in the Python geospatial stack. Their relationship and requirements regarding raster data and GDAL drivers are as follows: Leafmap and Optional Dependencies: Leafmap provides extra install targets to manage its dependencies based on use case [1][2]. For raster data support, you can use: pip install "leafmap[raster]" This installs essential raster-handling libraries, including localtileserver, rioxarray, and relevant NetCDF/HDF5 support packages (e.g., netcdf4, h5netcdf, h5py) [2][3]. localtileserver and rioxarray: localtileserver uses rioxarray to enable visualization of multi-dimensional datasets like NetCDF, Zarr, and HDF5 [4][5]. You can explicitly install these dependencies for localtileserver via: pip install localtileserver[xarray] This ensures that rioxarray and xarray are available, allowing the server to handle data formats that rioxarray supports [4][5]. GDAL HDF4 Driver and Pip Wheels: The HDF4 format is a legacy data format [6][7]. The standard GDAL Python bindings available on PyPI (the gdal package) do not ship as pre-compiled "manylinux" or "macosx" wheels that bundle all native libraries; instead, they are source distributions that require a system-level installation of libgdal and its development headers (e.g., libgdal-dev) [8][9][10]. Because of this, whether the HDF4 driver is available depends on how your local system's GDAL library was compiled [6][10]. If you face difficulties with GDAL dependencies or specific driver support (like HDF4) via pip, the recommended approach is to use conda/mamba, which provides pre-built binaries with comprehensive driver support through the conda-forge channel [1][11]: mamba create -n geo leafmap geopandas localtileserver python -c conda-forge Alternatively, some newer community-driven packages (e.g., pyramids-gis) offer self-contained wheels that bundle GDAL/HDF4 native libraries on specific platforms to simplify installation, though these are independent of the standard GDAL pip package [7].

Citations:


Install the raster dependencies before using local rasters.

Uncommenting this command installs bare leafmap, missing localtileserver; later cells call m.add_raster and m.split_map with local GeoTIFFs. Use leafmap[raster], e.g. "leafmap[raster]", since that extra includes the required raster backend dependencies. Also ensure GDAL has the HDF4 driver available for rxr.open_rasterio, because standard pip GDAL/Rasterio wheels do not guarantee all native drivers.

Proposed setup fix
-    "# %pip install leafmap earthaccess rioxarray matplotlib"
+    "# %pip install \"leafmap[raster]\" earthaccess rioxarray matplotlib"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"# %pip install leafmap earthaccess rioxarray matplotlib"
"# %pip install \"leafmap[raster]\" earthaccess rioxarray matplotlib"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/notebooks/117_urban_heat_island.ipynb` at line 40, Update the notebook’s
commented dependency-install command to use the raster-enabled leafmap extra
(`leafmap[raster]`) instead of bare `leafmap`, and ensure the setup documents or
provisions GDAL with HDF4 support for `rxr.open_rasterio` before the local
raster cells use `m.add_raster` and `m.split_map`.

@giswqs
giswqs merged commit c743a83 into opengeos:master Aug 2, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants