Land Use Land Cover (LULC) — Bhuvan/NRSC¶
India's national land mapping — track how land use has changed from 2005 to 2023 at 1:50,000 scale.
What Is LULC?¶
Land Use Land Cover (LULC) maps show what the land surface looks like — whether it's a forest, a paddy field, a city, a water body, or a wasteland. NRSC produces LULC maps for all of India using satellite images from ResourceSat (LISS-III and LISS-IV sensors).
Having LULC at multiple time points (2005–2023) allows you to detect: - Urban expansion eating into agricultural land - Forest degradation or recovery - Wetland conversion - Agricultural intensification (double/triple cropping)
LULC Class System¶
NRSC uses a hierarchical legend with 3 levels of detail:
| Level 1 (Broad) | Level 2 (Detailed) | Level 3 (Specific) |
|---|---|---|
| Agriculture | Kharif cropland | Paddy, Jowar, Bajra... |
| Rabi cropland | Wheat, Mustard... | |
| Double/Triple crop | Irrigated, Unirrigated | |
| Forest | Dense Forest | >70% canopy |
| Open Forest | 10-40% canopy | |
| Mangroves | Coastal | |
| Wasteland | Degraded | Various types |
| Barren | Rocky, sandy | |
| Built-up | Urban | Cities, towns |
| Industrial | Factories, mines | |
| Water Bodies | Reservoirs | Dams |
| Rivers | Perennial, seasonal | |
| Ponds | Village tanks | |
| Wetlands | Inland | Lakes, swamps |
| Coastal | Estuaries, tidal flats |
The full 48-class legend is available in the NRSC LULC technical document on bhuvan.nrsc.gov.in.
How to Download LULC Data¶
Step 1: Register on Bhuvan¶
- Go to bhuvan.nrsc.gov.in → Register
- Choose "Research" as purpose of use
Step 2: Download State/District LULC¶
- After login: Go to "Thematic Data" → "Land Use"
- Select Year (2005, 2011, 2015, 2017, 2021, 2023)
- Select State
- Download GeoTIFF (raster) or Shapefile (vector)
Step 3: Open in QGIS¶
- Drag the downloaded GeoTIFF into QGIS
- Right-click layer → Properties → Symbology
- Change to Paletted/Unique Values → Classify
- Each pixel value (1–48) represents a land class
- Download the NRSC colour scheme file (.qml) from Bhuvan for correct colours
Python: Calculate Land Class Areas¶
import rasterio
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# LULC legend (simplified)
LULC_CLASSES = {
1: 'Kharif Cropland',
2: 'Rabi Cropland',
3: 'Double/Triple Cropland',
4: 'Current Fallow',
5: 'Other Fallow',
6: 'Dense Forest',
7: 'Open Forest',
8: 'Scrub Forest',
9: 'Mangroves',
10: 'Built-up Urban',
11: 'Built-up Industrial',
12: 'Cropland + Trees',
13: 'Plantations',
14: 'Grassland/Grazing',
15: 'Wetland',
16: 'Water Body',
17: 'Barren/Unculturable',
18: 'Shifting Cultivation',
}
def calculate_lulc_areas(tif_path: str) -> pd.DataFrame:
"""Calculate area of each LULC class in km²."""
with rasterio.open(tif_path) as src:
data = src.read(1)
# Pixel size in degrees (approximately 0.0005° ≈ 56m at equator)
pixel_area_km2 = abs(src.transform.a * src.transform.e) * 111 * 111
unique, counts = np.unique(data[data != src.nodata if hasattr(src, 'nodata') else data != -9999],
return_counts=True)
df = pd.DataFrame({'class_id': unique, 'pixel_count': counts})
df['area_km2'] = df['pixel_count'] * pixel_area_km2
df['class_name'] = df['class_id'].map(LULC_CLASSES).fillna('Other')
df = df.sort_values('area_km2', ascending=False)
return df
# Analyse 2005 and 2023 LULC
lulc_2005 = calculate_lulc_areas("maharashtra_lulc_2005.tif")
lulc_2023 = calculate_lulc_areas("maharashtra_lulc_2023.tif")
# Compare
merged = lulc_2005.merge(lulc_2023, on='class_name', suffixes=('_2005', '_2023'))
merged['change_km2'] = merged['area_km2_2023'] - merged['area_km2_2005']
merged['change_pct'] = (merged['change_km2'] / merged['area_km2_2005']) * 100
print("\nLand Use Change 2005 to 2023 — Maharashtra")
print(merged[['class_name', 'area_km2_2005', 'area_km2_2023', 'change_pct']].to_string())
✏️ Practice Exercise¶
Exercise 3.2 — Urban Expansion Analysis
Goal: Calculate how much urban area has grown in your district from 2005 to 2023.
- Download LULC 2005 and LULC 2023 GeoTIFF for your state from Bhuvan
- Open QGIS → Load both files
- Clip both to your district using Raster → Extraction → Clip Raster by Mask Layer
- Use Raster → Raster Calculator:
- Expression:
("lulc_2023@1" = 10) - ("lulc_2005@1" = 10) - This gives +1 where urban grew, -1 where it shrank, 0 where unchanged
- Count pixels using Raster → Analysis → Raster Layer Statistics
Or in Python:
import rasterio
import numpy as np
with rasterio.open("district_lulc_2005.tif") as s1:
lulc05 = s1.read(1)
pixel_area = abs(s1.transform.a * s1.transform.e) * 111*111 # km²
with rasterio.open("district_lulc_2023.tif") as s2:
lulc23 = s2.read(1)
urban_2005 = np.sum(lulc05 == 10) * pixel_area
urban_2023 = np.sum(lulc23 == 10) * pixel_area
print(f"Urban area 2005: {urban_2005:.1f} km²")
print(f"Urban area 2023: {urban_2023:.1f} km²")
print(f"Increase: {urban_2023 - urban_2005:.1f} km² ({((urban_2023-urban_2005)/urban_2005)*100:.1f}%)")
Next Dataset: Forest Cover — FSI →