Developer Hub

Programming for GIS

Automate workflows and analyze geospatial data using programming structures. Reference robust code snippets for Python and JavaScript ecosystems.

Code Database

GeoPandas

Load and Display Shapefile

import geopandas as gpd
import matplotlib.pyplot as plt

# Load shapefile
gdf = gpd.read_file('countries.shp')

# Display first 5 rows
print(gdf.head())
print(f"CRS: {gdf.crs}")
print(f"Features: {len(gdf)}")

# Plot the data
fig, ax = plt.subplots(figsize=(12, 8))
gdf.plot(ax=ax, edgecolor='black', linewidth=0.5)
plt.title('World Countries')
plt.show()
GeoPandas

Spatial Operations: Buffer & Clip

import geopandas as gpd

# Load data
cities = gpd.read_file('cities.shp')
region = gpd.read_file('region.shp')

# Create 50km buffer around cities
cities_buffered = cities.copy()
cities_buffered['geometry'] = cities.buffer(50000)  # in meters

# Clip buffered cities to region
clipped = gpd.clip(cities_buffered, region)

# Spatial join: find which region each city belongs to
joined = gpd.sjoin(cities, region, how='inner', predicate='within')
print(joined[['city_name', 'region_name']])

# Save result
clipped.to_file('cities_buffered_clipped.shp')
GeoPandas

Area Calculation & Dissolve

import geopandas as gpd

# Load districts shapefile
districts = gpd.read_file('districts.shp')

# Reproject to UTM for accurate area calculation
districts_utm = districts.to_crs(epsg=32643)

# Calculate area in square kilometers
districts_utm['area_sqkm'] = districts_utm.geometry.area / 1e6

# Dissolve districts by state name
states = districts_utm.dissolve(by='state_name', aggfunc='sum')

# Calculate population density
states['pop_density'] = states['population'] / states['area_sqkm']

# Export as GeoJSON
states.to_file('states_analysis.geojson', driver='GeoJSON')
GDAL

Read Raster Data & Metadata

from osgeo import gdal
import numpy as np

# Open raster file
ds = gdal.Open('dem.tif')
band = ds.GetRasterBand(1)

# Get metadata
print(f'Projection: {ds.GetProjection()}')
print(f'Size: {ds.RasterXSize} x {ds.RasterYSize}')
print(f'Bands: {ds.RasterCount}')

# Read data as NumPy array
data = band.ReadAsArray()
print(f'Min elevation: {np.nanmin(data):.1f} m')
print(f'Max elevation: {np.nanmax(data):.1f} m')

# Get geotransform (coordinates)
gt = ds.GetGeoTransform()
print(f'Origin: ({gt[0]}, {gt[3]})')
print(f'Pixel size: {gt[1]} x {abs(gt[5])}')
ds = None
Rasterio

Calculate NDVI from Satellite Bands

import rasterio
import numpy as np

# Read NIR and Red bands
with rasterio.open('sentinel2_B08_nir.tif') as nir_src:
    nir = nir_src.read(1).astype(float)
    profile = nir_src.profile

with rasterio.open('sentinel2_B04_red.tif') as red_src:
    red = red_src.read(1).astype(float)

# Calculate NDVI
np.seterr(divide='ignore', invalid='ignore')
ndvi = (nir - red) / (nir + red)
ndvi = np.where(np.isfinite(ndvi), ndvi, 0)

# Save NDVI raster
profile.update(dtype=rasterio.float32, count=1)
with rasterio.open('ndvi_output.tif', 'w', **profile) as dst:
    dst.write(ndvi.astype(np.float32), 1)
Shapely

Create & Manipulate Geometries

from shapely.geometry import Point, LineString, Polygon
from shapely.ops import unary_union

# Create geometries
point = Point(77.2090, 28.6139)  # New Delhi
line = LineString([(77.2, 28.6), (72.8, 19.0)])  # Delhi to Mumbai
polygon = Polygon([(76, 28), (78, 28), (78, 26), (76, 26)])

# Operations
buffer = point.buffer(0.5)  # ~50km buffer in degrees
print(f'Contains point: {polygon.contains(point)}')

# Intersection
intersection = buffer.intersection(polygon)
print(f'Intersection area: {intersection.area:.4f}')

# Union of multiple polygons
poly2 = Polygon([(77, 27), (79, 27), (79, 25), (77, 25)])
merged = unary_union([polygon, poly2])
Google Earth Engine

Calculate NDVI Time Series

// Define area of interest
var roi = ee.Geometry.Point([77.2090, 28.6139]);

// Load Sentinel-2 collection
var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(roi)
  .filterDate('2023-01-01', '2023-12-31')
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20));

// Calculate NDVI for each image
var ndviCollection = s2.map(function(image) {
  var ndvi = image.normalizedDifference(['B8', 'B4'])
    .rename('NDVI');
  return ndvi.set('system:time_start', 
    image.get('system:time_start'));
});

// Create time series chart
var chart = ui.Chart.image.series(
  ndviCollection, roi, ee.Reducer.mean(), 10)
  .setOptions({title: 'NDVI Time Series 2023'});
print(chart);

// Display on map
var meanNDVI = ndviCollection.mean();
Map.centerObject(roi, 10);
Map.addLayer(meanNDVI, 
  {min: 0, max: 0.8, palette: ['red','yellow','green']},
  'Mean NDVI');
Google Earth Engine

Land Use Classification (Random Forest)

// Load Sentinel-2 composite
var image = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterDate('2023-06-01', '2023-09-01')
  .filterBounds(roi)
  .median()
  .select(['B2','B3','B4','B5','B6','B7','B8','B11','B12']);

// Training data (FeatureCollection with class labels)
var training = image.sampleRegions({
  collection: trainingPoints,
  properties: ['landcover'],
  scale: 10
});

// Train Random Forest classifier
var classifier = ee.Classifier.smileRandomForest(100)
  .train(training, 'landcover');

// Classify the image
var classified = image.classify(classifier);

// Display results
Map.addLayer(classified, {
  min: 0, max: 5,
  palette: ['green','darkgreen','blue','yellow','red','gray']
}, 'Land Cover Classification');

Learning Curriculum

Python Basics for GIS

Beginner
  • > Variables and Data Types
  • > Functions and Modules
  • > Working with Arrays
  • > Error Handling

GeoPandas

Intermediate
  • > Spatial Operations
  • > Attribute Queries
  • > Dissolve & Merge
  • > CRS Management

Raster Processing

Intermediate
  • > GDAL/OGR Fundamentals
  • > Rasterio Data I/O
  • > Band Math
  • > Cloud-Optimized GeoTIFF

Earth Engine API

Advanced
  • > JavaScript API basics
  • > Image Collections
  • > Filters & Reducers
  • > Classification