There are only two numbers needed to describe any location on Earth — latitude and longitude. With Python, those two numbers can become maps, distance calculations, and satellite analysis. Here's everything you need to get started.
What Is Geospatial Data?
Geospatial data is any data that has a location attached to it. It comes in two forms:
- Vector — discrete shapes. A city is a point. A road is a line. A state boundary is a polygon.
- Raster — a grid of pixels. Satellite images, elevation maps, rainfall data. Think of it as a photograph with coordinates baked in.
The Three Libraries You Actually Need
- Shapely — creates geometry objects (points, lines, polygons) in Python.
- GeoPandas — like pandas, but every row has a location. Reads shapefiles, GeoJSON, and CSVs with coordinates. This is your main tool.
- Folium — turns your data into interactive web maps. One line to save as HTML.
pip install geopandas shapely folium
Your First 10 Lines of Geospatial Python
from shapely.geometry import Point, Polygon
# Neyveli, Tamil Nadu
neyveli = Point(79.4754, 11.5985) # lon first, lat second
# Simplified Tamil Nadu boundary
tamil_nadu = Polygon([
(76.2, 8.0), (80.4, 8.0),
(80.4, 13.5), (76.2, 13.5)
])
print(tamil_nadu.contains(neyveli)) # True
That's it. You've created a real location, drawn a boundary, and checked containment — the three building blocks of almost every spatial analysis.
The One Concept That Trips Everyone Up — CRS
CRS stands for Coordinate Reference System. It's the math that maps coordinates onto Earth's curved surface.
The problem: if your data is in GPS degrees (EPSG:4326) and you calculate a distance, you'll get degrees back — not kilometers. Useless.
The fix: reproject to a metric system before measuring.
import geopandas as gpd
from shapely.geometry import Point
chennai = gpd.GeoSeries([Point(80.2707, 13.0827)], crs="EPSG:4326")
mumbai = gpd.GeoSeries([Point(72.8777, 19.0760)], crs="EPSG:4326")
# Reproject to meters (UTM Zone 44N — South India)
dist = chennai.to_crs("EPSG:32644").distance(
mumbai.to_crs("EPSG:32644")
).values[0]
print(f"{dist/1000:.0f} km") # 1048 km ✓
Simple rule: store in EPSG:4326, measure in EPSG:32644.
Loading Real Data and Making a Map
import geopandas as gpd
import folium
# Built-in world dataset
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# Filter and plot
asia = world[world['continent'] == 'Asia']
asia.plot(column='gdp_md_est', cmap='YlOrRd', legend=True)
# Interactive map
m = folium.Map(location=[11.0, 78.6], zoom_start=6)
folium.Marker([11.5985, 79.4754], popup="Neyveli").add_to(m)
m.save('map.html') # open in your browser
Three lines to filter a continent. Three lines to make a zoomable web map. That's the power of this stack.
What to Build First
Pick a question about a place you know and answer it with data. A few starter ideas:
- Load Tamil Nadu district boundaries → join with census data → make a population density map
- Find all cities within 200 km of your city using a buffer
- Download Sentinel-2 satellite imagery of your district → calculate NDVI vegetation health
All the data you need is free — Bhuvan (ISRO) for India-specific layers, Natural Earth for global data, Copernicus Hub for satellite imagery.
The Bottom Line
You need three libraries. One coordinate system rule. And a question about a real place.
The rest is just building from there.