Remote Sensing

Sentinel-2, spectral indices and change detection from space.

Farm check answer for Lilongwe, Malawi, on 30 October 2026: the rains have not started yet and usually start between 15 November and 18 December

Article Remote Sensing

Farm check: has the rain started on your farm?

A free, phone-friendly check for any farm: whether the rains have started, when they usually start, rain and heat for the next 10 days and how green the crops are. Examples from Lilongwe, Malawi, and Gazipur, Bangladesh.

Beginner 5 min read

Season condition answer for Marsabit, Kenya, October to December 2022, with rainfall below normal and vegetation the lowest since 2001

Article Remote Sensing

Free community tools: season condition and flood impact for any district

Two free tools for any district: is this season's rain and crop growth better or worse than usual, and where did it flood and how many people live there? Worked examples from Marsabit, Kenya, in 2022 and Feni, Bangladesh, in 2024.

Beginner 5 min read

The climate tool map with a rectangle drawn over north Evia, Greece, its corner handles visible and a readout of 35 by 28 km within the limits

Article Remote Sensing

Climate time-series tools: charts and time-lapses for any place

An introduction to the TechnicalGIS climate time-series tools: five open datasets, how to draw an area on the map, worked examples from London, north Evia, Nairobi and Las Vegas, the processing limits and the terms for reusing every output.

Beginner 8 min read

Bar chart comparing the area of each land cover class in Ireland from WorldCover pixel counting with the error-adjusted estimate and its 95% confidence interval.

Tutorial Remote Sensing

Land cover accuracy assessment in Python: confusion matrix, Olofsson area estimates and sample size

Assess a real land cover map in Python: ESA WorldCover 2021 against 8,597 Eurostat LUCAS 2022 field survey points in Ireland. Build the confusion matrix, compute overall, user's and producer's accuracy, see why kappa is discouraged, and use the Olofsson et al. (2014) stratified estimators to get error-adjusted areas with 95% confidence intervals and to plan a new stratified random sample.

Advanced 20 min read

Map of the Theil-Sen slope of growing-season NDVI from 2001 to 2024 on the Loess Plateau between Yan'an and Yulin, almost entirely teal (greening), with a few brown browning patches near Yan'an and Yulin.

Tutorial Remote Sensing

Mann-Kendall trend test on rasters in Python: Theil-Sen NDVI trends with xarray

Run a pixel-wise Mann-Kendall trend test and Theil-Sen slope on 24 years of MODIS NDVI in Python. Read MOD13A1 from the Microsoft Planetary Computer, mask it with the QA layer, aggregate to growing-season means, vectorise the tests with xarray.apply_ufunc (checked against pymannkendall), compare the seasonal and modified Mann-Kendall tests, control the false discovery rate across 229,229 pixels, and map greening and browning on China's Loess Plateau.

Advanced 16 min read

Tutorial Python

Methane plume detection in Python with NASA EMIT: mapping and quantifying landfill plumes

Detect and quantify methane plumes in Python with NASA's EMIT imaging spectrometer: load open EMIT methane enhancement data from NASA VEDA without a login, separate three Dallas-Fort Worth landfill plumes from the noise, compute the integrated mass enhancement, estimate emission rates with ERA5 winds, and compare them with EPA greenhouse gas inventory figures.

Advanced 17 min read

Three panels of the same 1 km by 0.7 km area at Salford Quays. Left: square WorldCover pixels, mostly red built-up land with blue dock basins and small green and yellow patches. Middle: the same area as 142 polygons with black outlines that follow the pixel staircase. Right: the polygons after coverage simplification at 10 m, with smoother outlines and no gaps between them.

Tutorial Python Part 3 of 3

Raster to vector in Python: polygonize with rasterio, rasterize boundaries and convert a GeoTIFF to a Cloud Optimized GeoTIFF

Convert raster to vector in Python with rasterio.features.shapes on 10 m ESA WorldCover for Greater Manchester: polygonize water and built-up land, fix invalid polygons, simplify without gaps, rasterize ONS district boundaries for land-cover shares, then write and validate a Cloud Optimized GeoTIFF with rio-cogeo and measure HTTP range reads.

Intermediate 14 min read

Tutorial Python

Sentinel-1 soil moisture in Python: change detection checked against COSMOS-UK

Estimate surface soil moisture from free Sentinel-1 radar in Python with the TU Wien change-detection method. Build dry and wet references per orbit, map relative soil moisture at 100 m, and test it honestly against four COSMOS-UK stations and their rain gauges.

Intermediate 13 min read

Two habitat maps of the Dark Peak side by side. Left: the rule-based map from Sentinel-2, with purple blanket bog and lilac heath on the Kinder and Bleaklow plateaux, orange bracken on the valley sides, green grassland and woodland in the valleys and blue reservoirs in the Derwent valley. Right: Living England 2022-23 for the same area, with smoother patches of the same classes.

Tutorial Python Part 1 of 5

Habitat mapping with Sentinel-2 in Python: spectral index rules and an honest accuracy assessment

Map blanket bog, heath, bracken, grassland, woodland, water and built-up land in the Peak District from 2023 Sentinel-2 seasonal composites with an eight-rule spectral index classifier, then assess it properly: a confusion matrix, user's and producer's accuracy, kappa and its caveats, block-bootstrap confidence intervals, and why a random train/test split overstates accuracy.

Beginner 19 min read

Time series of line-of-sight uplift at the SENG GNSS station at Svartsengi in Iceland from 2024 to 2026: red InSAR points and a grey GNSS line rise in a sawtooth of six inflation phases separated by eruptions, and agree closely once each phase is restarted at zero.

Tutorial Python Part 3 of 3

InSAR time series in Python: Svartsengi inflation cycles validated with GNSS

Build an SBAS InSAR time series in Python from 364 COMET LiCSAR Sentinel-1 interferograms of the Svartsengi volcano in Iceland. Check unwrapping with phase closure, invert pixel by pixel with weighted least squares, project GNSS east, north and up into the line of sight, and validate six inflation–eruption cycles against the SENG station.

Advanced 21 min read

Three habitat maps of the Dark Peak side by side. Left: the noisy Part 1 rule-based map. Centre: the LightGBM map, with smooth purple blanket bog on the Kinder and Bleaklow plateaux, lilac heath around them, orange bracken on the valley sides, yellow semi-natural grassland in the south, green grassland and woodland in the valleys and blue reservoirs. Right: Living England 2022-23, which the LightGBM map closely resembles.

Tutorial Python Part 2 of 5

Habitat classification with LightGBM in Python: Sentinel-2, Sentinel-1 and terrain fusion

Classify nine upland habitats in the Peak District with LightGBM on 77 multi-temporal features: seasonal Sentinel-2 bands and indices, Sentinel-1 VV and VH backscatter and Copernicus DEM terrain. Tune with spatial-fold cross-validation and class weights, run an S2 / S2+S1 / S2+S1+terrain ablation, explain the model with TreeSHAP and permutation importance, and compare it with a random forest and the Part 1 rules on the same test blocks.

Intermediate 21 min read

A map of vertical uplift at Svartsengi in Iceland with the best-fitting Mogi point source, an Okada sill outline and the published source location plotted near the centre of the uplift.

Tutorial Python Part 2 of 3

Mogi model inversion in Python: magma depth and volume from InSAR at Svartsengi, Iceland

Invert Sentinel-1 InSAR for a volcanic source in Python: write Mogi point-source and Okada (1985) sill forward models in NumPy, downsample ascending and descending LOS maps with a quadtree, fit depth and volume change by weighted least squares with scipy.optimize, and estimate uncertainties with a Monte Carlo of correlated noise, compared with published results.

Advanced 17 min read

Tutorial Python

Sentinel-2 cloud and cloud-shadow masking in Python: SCL vs s2cloudless vs OmniCloudMask

Mask clouds and cloud shadows in Sentinel-2 L2A imagery with Python. Compare the Scene Classification Layer (SCL), s2cloudless, OmniCloudMask and a simple threshold over the Lake District, measure how far they agree, score them against 186 reference points and build a cloud-free median composite.

Intermediate 14 min read

Three panels of the Cairngorms on 25 November 2025: a true-colour Sentinel-2 image with snow on the plateaux and long shadows in the glens; the NDSI, blue over snow and red over forest and bare ground; and a snow map over hillshade, with snow in blue on the high ground around Cairn Gorm, Ben Macdui, Braeriach, Beinn a' Bhuird and Ben Avon, covering 57% of the clear land.

Tutorial Python

Snow cover mapping with NDSI in Python: Sentinel-2 and MODIS over the Cairngorms

Map snow cover in Python with the Normalised Difference Snow Index (NDSI) from Sentinel-2 and the daily MODIS snow product on the Microsoft Planetary Computer: choosing the NDSI threshold, separating snow from cloud, snow-covered area through the winter of 2025–26 in the Cairngorms, and the snowline by elevation and aspect with the Copernicus DEM.

Intermediate 15 min read

Two habitat maps of the Dark Peak side by side. Left: the map from AlphaEarth embeddings and logistic regression, with large purple blanket bog areas on Kinder Scout and Bleaklow, lilac heath around them, orange bracken on the valley sides, yellow and light green grassland in the south and west, and blue reservoirs in the Derwent valley. Right: Living England 2022-23 for the same area, with very similar patterns.

Tutorial Python Part 5 of 5

AlphaEarth satellite embeddings in Python: few-shot habitat mapping, uncertainty and area estimates

Use Google DeepMind's AlphaEarth Foundations satellite embeddings, a geospatial foundation model, in Python without a login. Classify nine Peak District habitats with a linear model, compare a few-shot learning curve against raw Sentinel-2 bands, map uncertainty, check calibration, simulate active learning, and estimate habitat areas with confidence intervals from a stratified random sample (Olofsson et al. 2014).

Advanced 24 min read

Map of ITS_LIVE surface speed around Jakobshavn Isbræ on a logarithmic colour scale: a narrow channel of ice faster than 10 km per year runs west into the fjord, fed by a broad fan of slower ice from the ice sheet. A white flowline runs up the trunk with points A to D marked at 5, 15, 30 and 60 km, and an inset shows the location on the west coast of Greenland.

Tutorial Python

Glacier velocity in Python with NASA ITS_LIVE: Jakobshavn Isbræ, 1985–2025

Map glacier velocity in Python with NASA's ITS_LIVE Zarr datacubes on AWS, with no login: velocity maps, a flowline traced from the velocity field, 40 years of speed profiles, seasonal and multi-year time series from 80,568 filtered image pairs, and strain rates and flow directions on Jakobshavn Isbræ (Sermeq Kujalleq), Greenland's fastest glacier.

Advanced 15 min read

A Sentinel-1 interferogram of the Reykjanes Peninsula in Iceland with a bullseye of concentric colour fringes centred just west of the Svartsengi GNSS station, beside the unwrapped displacement and coherence maps.

Tutorial Python Part 1 of 3

InSAR volcano deformation in Python: mapping magma inflation at Svartsengi, Iceland, with Sentinel-1

Map volcano deformation with Sentinel-1 InSAR in Python: stream free COMET LiCSAR interferograms of the Svartsengi volcanic system in Iceland, read wrapped and unwrapped phase and coherence, count fringes, convert phase to line-of-sight millimetres, and combine ascending and descending tracks into vertical and east–west motion, checked against GNSS.

Advanced 19 min read

Four panels of the same 4 by 3 km area of the Edale valley and the southern edge of Kinder Scout. Top left: a true colour Sentinel-2 image of green fields and brown moorland. Top right: a pixel-based habitat map speckled with isolated pixels of other classes. Bottom left: the object-based map, with the same habitats in clean patches that follow field boundaries. Bottom right: the Living England reference map.

Tutorial Python Part 3 of 5

Object-based image analysis in Python: OBIA habitat classification with Sentinel-2

Segment 2023 Sentinel-2 seasonal composites of the Peak District into image objects with scikit-image SLIC and Felzenszwalb, tune the segment size against Living England boundaries, compute per-object statistics, shape and GLCM texture with NumPy, classify the objects with LightGBM and compare OBIA with a pixel-based classifier on accuracy, salt-and-pepper noise and patch counts. Then export the habitat objects as GeoPackage polygons.

Advanced 21 min read

Two habitat maps of the Dark Peak side by side. Left: the TempCNN time-series map at 10 m, with purple blanket bog on the Kinder and Bleaklow plateaux, lilac heath around it, orange bracken on valley sides, yellow and green grassland in the south and west, dark green conifers and blue reservoirs in the Derwent valley. Right: Living England 2022-23 for the same area, which looks very similar but has more heath.

Tutorial Python Part 4 of 5

Satellite image time series classification with deep learning: TempCNN and L-TAE in PyTorch on a CPU

Classify habitats from a full year of cloudy, irregular Sentinel-2 observations with two temporal neural networks in PyTorch: a 1D convolutional TempCNN and a lightweight temporal attention encoder (L-TAE) with day-of-year positional encoding. Compare masking with gap-filling, test against a LightGBM baseline on spatial blocks, read which dates matter from attention and occlusion, and predict a wall-to-wall 10 m map on a CPU.

Advanced 24 min read

Map of the Holderness coast from Skipsea to Withernsea in greyscale Sentinel-2, with each 100 m transect coloured by its shoreline change rate from 2017 to 2026: mostly red (retreat), with blue (advance) patches north of Hornsea, at Mappleton and near Grimston.

Tutorial Python

Coastal erosion and shoreline change from Sentinel-2 in Python (Holderness, 2017–2026)

Measure shoreline change on one of Europe's fastest-eroding coasts with free Sentinel-2 imagery and Python: MNDWI and Otsu thresholding, sub-pixel shorelines with find_contours, shore-normal transects, a tide correction from open tide-gauge data, end-point and linear regression rates, and an honest comparison with East Riding of Yorkshire Council's cliff monitoring.

Advanced 21 min read

Tutorial Python

Deforestation detection in Python with Global Forest Change data (Rondônia, 2001–2025)

Map forest loss and deforestation in Python with the Hansen/UMD Global Forest Change v1.13 data: read the open tiles with no login, compute loss by year in hectares with correct pixel areas, compare Landsat and Sentinel-2 images before and after, and check the GFC loss year against Sentinel-2 NBR and MODIS burned area for central Rondônia, Brazil.

Intermediate 15 min read

Two land cover maps of a 30 km square around Leicester side by side: the U-Net prediction on the left and the reference labels on the right. Both show the city in grey and red in the centre, surrounded by farmland in pale green, woods in dark green and reservoirs in blue. The prediction's city is smoother, with fewer separate red buildings.

Tutorial Python Part 3 of 3

Deep learning inference on large rasters: sliding-window prediction, COGs and polygons in Python

Run a trained PyTorch U-Net over a whole Sentinel-2 scene of a city it has never seen: tiled sliding-window inference on a large GeoTIFF with overlapping, blended windows, a georeferenced Cloud Optimised GeoTIFF of classes and confidence, raster-to-vector polygons with rasterio.features.shapes in a GeoPackage, and an honest check against reference labels.

Advanced 13 min read

Four rows of Sentinel-2 test chips. Each row shows the image, the reference labels, the U-Net prediction and the disagreement in magenta. The prediction matches rivers, woods and fields closely, but in the city centre it draws buildings as blobs instead of separate roofs.

Tutorial Python Part 2 of 3

U-Net satellite image segmentation in PyTorch: a TorchGeo and Sentinel-2 tutorial on a CPU

Train a U-Net to segment Sentinel-2 imagery into buildings, built-up land, trees, grass and water with PyTorch, segmentation_models_pytorch and TorchGeo's Sentinel-2 pretrained ResNet-18 weights, on a CPU in five minutes. Real loss curves, per-class IoU and F1, a confusion matrix and an honest look at what limits accuracy.

Advanced 12 min read

Six 128 by 128 pixel Sentinel-2 image chips of Nottingham, each shown above the same chip with its label mask overlaid: a city centre with red buildings and grey streets, a suburb, a forest, farmland, flooded gravel pits in blue and an industrial estate.

Tutorial Python Part 1 of 3

Training data for deep learning on satellite imagery: Sentinel-2 image chips in Python

Build a labelled deep learning dataset from free data: stream a Sentinel-2 L2A composite from the Planetary Computer, rasterise Overture building footprints over ESA WorldCover, cut georeferenced image chips, split them by spatial block so the test set does not leak, check the class balance and load it all as a TorchGeo dataset.

Intermediate 13 min read

Tutorial Python Part 1 of 2

Sentinel-5P NO₂ in Python: mapping air pollution from TROPOMI over the UK and north-west Europe

Map nitrogen dioxide air pollution from Sentinel-5P TROPOMI Level-2 data in Python: stream a full year of orbits from the Planetary Computer, apply the qa_value > 0.75 filter, grid swaths to a regular raster, build monthly and seasonal composites, rank cities and measure the weekend drop, with an honest explanation of what a tropospheric column is.

Intermediate 17 min read

Tutorial Python

InSAR ground subsidence in Python: one year of Mexico City sinking, from Sentinel-1

Map ground subsidence with Sentinel-1 InSAR in Python: stream 170 real interferograms of Mexico City, convert unwrapped phase to millimetres of line-of-sight motion, mask low coherence, invert a small-baseline network into a time series, and cross-check the velocity with MintPy.

Advanced 17 min read

Tutorial Python

Burn severity mapping with Sentinel-2 and dNBR in Python (Saddleworth Moor 2018)

Map wildfire burn severity in Python with free Sentinel-2 imagery: NBR calculation, cloud and water masking with SCL, dNBR with an offset, USGS severity classes and burned hectares, a burn perimeter, fire progression, RdNBR and an eight-year recovery record for the 2018 Saddleworth Moor fire.

Intermediate 15 min read

Tutorial Python

Sentinel-1 crop monitoring in Python: SAR time series for wheat and oilseed rape

Monitor crops through cloud with free Sentinel-1 radar. Build VV, VH and VH/VV ratio time series for 247 fields in Cambridgeshire, beat speckle by field-averaging, read the growth signatures of winter wheat and oilseed rape, and compare with the gaps that cloud leaves in Sentinel-2 NDVI.

Intermediate 16 min read

Tutorial Python

Segment Anything on satellite and aerial imagery in Python: a samgeo tutorial

Run Meta's Segment Anything Model on high-resolution aerial imagery with segment-geospatial (samgeo), on a CPU. Generate masks automatically, vectorise them to a GeoPackage, filter them by area, shape and NDVI to find buildings, and prompt SAM with points and boxes, checked against OpenStreetMap.

Intermediate 14 min read

Tutorial Python

Land surface temperature from Landsat in Python: mapping London's urban heat island

Calculate land surface temperature from Landsat 8 and 9 Collection 2 Level-2 data in Python: ST_B10 scale and offset, QA_PIXEL cloud masking, LST by land cover and NDVI, an urban-rural transect, hotspots with OpenStreetMap and an honest comparison with air temperature, for London in the July 2022 heatwave.

Intermediate 17 min read

Tutorial Python

Sentinel-1 ship detection in Python: a CA-CFAR detector off the Port of Rotterdam

Detect ships in free Sentinel-1 SAR imagery with a cell-averaging CFAR detector written in NumPy and SciPy: mask the land, set a threshold from a speckle model, cluster detections into targets, reject wind turbines, sidelobes and ambiguities, compare VV with VH and export the vessels as GeoJSON.

Intermediate 16 min read

Tutorial Python

Sentinel-1 SAR flood mapping in Python: the 2022 Pakistan floods

Map the 2022 Sindh floods with free Sentinel-1 radar from the Microsoft Planetary Computer: convert backscatter to decibels, remove speckle with a Lee filter, pick a water threshold with Otsu's method, and measure the flood extent and how it receded over seven months.

Intermediate 10 min read

Cracked, dried mud on Lake Mead's exposed lake bed during the 2022 drought.

Article Remote Sensing

Monitoring Lake Mead Drought

A look at the dramatic fall in Lake Mead's water level during the 2022 drought.

Beginner 1 min read