CoPhil EO AI/ML Training - Day 1, Session 3
EU-Philippines CoPhil Programme
Python for Geospatial Data Analysis
Hands-on introduction to working with vector and raster data using Python
Format: Brief conceptual intro + Extended hands-on coding
Duration: 2 hours (15-20 min presentation + 100 min hands-on)
By the end of this session, you will be able to:
| Time | Topic | Duration |
|---|---|---|
| 00-15 min | Setup & Python Basics Recap | 15 min |
| 15-55 min | GeoPandas for Vector Data (HANDS-ON) | 40 min |
| 55-60 min | ☕ Break | 5 min |
| 60-110 min | Rasterio for Raster Data (HANDS-ON) | 50 min |
| 110-120 min | Summary & Next Steps | 10 min |
📓 Google Colab Notebook:
Day1_Session3_Python_Geospatial_Data.ipynb
Vector Data:
Raster Data:
Integration: Combining vector and raster for complete EO workflows
Why Python is the Leading Language for EO:
Complete Python Earth Observation Ecosystem organized by function
Python Connects Everything:
# Example workflow
import geopandas as gpd
import rasterio
from sklearn.ensemble import RandomForestClassifier
# Load vector training data
training = gpd.read_file('samples.geojson')
# Load satellite raster
with rasterio.open('sentinel2.tif') as src:
image = src.read()
# Extract features and train model
X, y = extract_features(image, training)
model = RandomForestClassifier()
model.fit(X, y)
# Predict on full image
prediction = model.predict(image)Vibrant Python Geospatial Community:
Documentation:
Community Support:
Learning Resources:
Advantages for Learning:
Main Components:

Two Ways to Execute Cells:
1. Click the Play Button
2. Keyboard Shortcuts
Output Appears Below Cell:
Text, plots, tables, errors all display inline.
Mounting Your Google Drive:
Benefits:
Most Common Libraries Pre-Installed:
NumPy, Pandas, Matplotlib, Scikit-learn
For Geospatial Libraries:
Note: Packages need reinstalling each session (Colab resets runtime)
Pandas + Geometry = GeoPandas
Definition:
Extension of Pandas for working with geospatial vector data
Key Concept:
Like a spreadsheet/table where one column contains geometries (points, lines, polygons)
Built On:
GeoPandas
Pandas + Geometry
Similar to Pandas DataFrame:
Regular DataFrame:
| Name | Population | Area |
|---|---|---|
| Manila | 1.78M | 42.88 |
| Cebu | 0.92M | 315 |
| Davao | 1.63M | 2444 |
GeoDataFrame:
| Name | Population | Area | geometry |
|---|---|---|---|
| Manila | 1.78M | 42.88 | POLYGON(…) |
| Cebu | 0.92M | 315 | POLYGON(…) |
| Davao | 1.63M | 2444 | POLYGON(…) |
Special “geometry” Column:
Contains spatial information (coordinates defining shapes)
What You Can Do with GeoPandas:
Loading and Visualizing:
import geopandas as gpd
import matplotlib.pyplot as plt
# Read Philippine provinces shapefile
provinces = gpd.read_file('philippines_provinces.shp')
# Examine data
print(provinces.head())
print(provinces.crs) # Check coordinate system
# Simple plot
provinces.plot(figsize=(10, 10),
edgecolor='black',
facecolor='lightblue')
plt.title('Philippine Provinces')
plt.show()GeoPandas Plotting:
# Color by attribute
provinces.plot(column='population',
cmap='YlOrRd',
legend=True,
figsize=(12, 10))
plt.title('Population by Province')
# Add basemap (with contextily)
import contextily as ctx
provinces_web_mercator = provinces.to_crs(epsg=3857)
ax = provinces_web_mercator.plot(figsize=(15, 15),
alpha=0.5)
ctx.add_basemap(ax)Common CRS for Philippines:
| EPSG | Name | Type | Units | Use Case |
|---|---|---|---|---|
| 4326 | WGS84 | Geographic | Degrees | Web maps, lat/lon |
| 32651 | UTM Zone 51N | Projected | Meters | Western PH, Manila |
| 32652 | UTM Zone 52N | Projected | Meters | Eastern PH, Mindanao |
| 3123 | PRS92 Zone III | Projected | Meters | National standard |
Rule: Use geographic (4326) for storage, projected (UTM) for analysis
UTM Zone 51N (EPSG:32651)
Coverage: - Metro Manila - Palawan - Western Luzon - Western Visayas
Most common for: - Urban analysis - Palawan studies - Manila projects
UTM Zone 52N (EPSG:32652)
Coverage: - Mindanao - Eastern Visayas - Bicol Region - Eastern Luzon
Most common for: - Mindanao analysis - Disaster mapping - Agricultural studies
NAMRIA Geoportal - Administrative boundaries - Topographic maps - Land cover 2020 - DEMs - www.geoportal.gov.ph
PhilSA - Satellite imagery - EO products - philsa.gov.ph
PSA - Census boundaries - Barangay data - psa.gov.ph
OpenStreetMap - Roads, buildings - extract.bbbike.org
Natural Earth - Country boundaries - naturalearthdata.com
All work with GeoPandas - just gpd.read_file()!
Python Wrapper for GDAL
Definition:
Clean, idiomatic Python library for reading and writing geospatial raster data
Why Not Use GDAL Directly?
Works With:
All formats GDAL supports - GeoTIFF, COG, NetCDF, HDF, etc.
Rasterio
Python Wrapper for GDAL
How Rasterio Represents Imagery:
3D NumPy Array:
(bands, rows, columns)
Basic Workflow:
import rasterio
import numpy as np
# Open raster file
with rasterio.open('sentinel2_10m.tif') as src:
# Read all bands
data = src.read()
# Read specific band
red_band = src.read(3)
# Get metadata
print(f"CRS: {src.crs}")
print(f"Transform: {src.transform}")
print(f"Width: {src.width}, Height: {src.height}")
print(f"Bounds: {src.bounds}")
print(f"Number of bands: {src.count}")Rasterio + NumPy = Powerful Processing
# Calculate NDVI
with rasterio.open('sentinel2_10m.tif') as src:
red = src.read(3).astype(float)
nir = src.read(4).astype(float)
# NDVI formula
ndvi = (nir - red) / (nir + red + 1e-8) # Small value prevents division by zero
# Apply threshold
vegetation_mask = ndvi > 0.3
# Calculate statistics
print(f"Mean NDVI: {np.mean(ndvi):.3f}")
print(f"Vegetation pixels: {np.sum(vegetation_mask)}")Key Indices for EO Analysis:
| Index | Formula | Purpose | Range |
|---|---|---|---|
| NDVI | (NIR - Red) / (NIR + Red) | Vegetation health | -1 to +1 |
| EVI | 2.5 × (NIR - Red) / (NIR + 6×Red - 7.5×Blue + 1) | Enhanced vegetation | -1 to +1 |
| NDWI | (Green - NIR) / (Green + NIR) | Water bodies | -1 to +1 |
| NDBI | (SWIR - NIR) / (SWIR + NIR) | Built-up areas | -1 to +1 |
Sentinel-2 Bands: Blue (B2), Green (B3), Red (B4), NIR (B8), SWIR (B11, B12)
Using NDVI for Philippine Rice Paddies:
# Calculate NDVI for Central Luzon rice area
with rasterio.open('sentinel2_central_luzon.tif') as src:
red = src.read(4).astype(float) # Band 4
nir = src.read(8).astype(float) # Band 8
# NDVI calculation
ndvi = (nir - red) / (nir + red + 1e-8)
# Classify vegetation health
bare_soil = ndvi < 0.2 # Recently planted / fallow
growing = (ndvi >= 0.2) & (ndvi < 0.5) # Early growth
mature = (ndvi >= 0.5) & (ndvi < 0.8) # Peak biomass
very_dense = ndvi >= 0.8 # Maximum vegetation
# Calculate rice area statistics
pixel_area = 100 # 10m x 10m = 100 m²
mature_rice_area_ha = np.sum(mature) * pixel_area / 10000
print(f"Mature rice area: {mature_rice_area_ha:.2f} hectares")Displaying Satellite Imagery:
import matplotlib.pyplot as plt
from rasterio.plot import show
# Open and display
with rasterio.open('sentinel2_10m.tif') as src:
# Show true color composite (RGB)
show((src, [3, 2, 1]), title='True Color')
# Show false color composite (NIR, Red, Green)
show((src, [4, 3, 2]), title='False Color (NIR-R-G)')
# Or read and plot with matplotlib
with rasterio.open('sentinel2_10m.tif') as src:
data = src.read([3, 2, 1]) # RGB
# Scale to 0-255 for display
data_scaled = np.clip(data / 3000, 0, 1)
plt.figure(figsize=(10, 10))
plt.imshow(np.moveaxis(data_scaled, 0, -1))
plt.title('Sentinel-2 True Color')
plt.axis('off')
plt.show()Notebook 1: Vector Data with GeoPandas
Notebook 2: Raster Data with Rasterio
Combining Both Data Types:
import geopandas as gpd
import rasterio
from rasterio.mask import mask
# Load vector boundary
aoi = gpd.read_file('study_area.geojson')
# Load raster
with rasterio.open('sentinel2.tif') as src:
# Clip raster to vector boundary
clipped_data, clipped_transform = mask(
src,
aoi.geometry,
crop=True
)
# Update metadata for output
out_meta = src.meta.copy()
out_meta.update({
"height": clipped_data.shape[1],
"width": clipped_data.shape[2],
"transform": clipped_transform
})What You’ll Learn:
Access Today’s Notebooks:
Notebook 1: Vector Data
[Link will be provided in chat]
Notebook 2: Raster Data
[Link will be provided in chat]
Make a Copy:
File → Save a copy in Drive (so you can edit and experiment)
As We Work Through Notebooks:
GeoPandas:
Rasterio:
Integration:
For AI/ML in Earth Observation:
Today’s Skills Enable:
Day 2:
Day 3:
Day 4:
Mastering these fundamentals now will make everything else smoother.
Stretch Break
Stand up • Grab water • Back in 5 minutes
Open Your Notebooks
We’ll start with:
Vector Data Analysis using GeoPandas
Remember:
Instructors Available:
Pacing:
Goal:
Everyone completes core exercises, understands concepts, ready for GEE
What You’ve Learned:
✅ Google Colab setup for geospatial work
✅ GeoPandas for vector data (load, visualize, analyze)
✅ Rasterio for raster data (read, process, visualize)
✅ Coordinate systems and projections
✅ Basic geospatial operations (clip, reproject, crop)
✅ Data preparation for ML workflows
Common Questions:
Coming up:
Get ready for GEE! 🌍
Everyone completes core exercises with understanding, not just copying code.
Any questions about the tools or approach?
Opening Notebook 1: GeoPandas for Vector Data
Day 1 Session 3 | Python Geospatial | 20-23 October 2025