How much water fits inside Waterloo’s water mains? A geometry lesson on city data
The City of Waterloo publishes the pipes that carry its drinking water as open data. Students read the file, model each pipe as a cylinder and then argue about what the model leaves out. Every count, sum and volume below is ours, not the City’s.
The dataset is called Water Distribution Mains. The City’s description says it represents the pipeline system that conveys municipal drinking water through a network of distribution mains within the City of Waterloo, and it adds a caution that teachers should read aloud: these records are based upon available information, compiled from a variety of sources, some of which has not been verified. We queried the layer on 22 October 2026 and received 8,118 rows, each one a length of pipe with a diameter, a length in metres, a material, an install date and an owner.
| Diameter | Rows | Length (km) | Modelled volume (cubic metres) |
|---|---|---|---|
| 50 | 78 | 3.74 | 7 |
| 100 | 385 | 17.05 | 134 |
| 150 | 3,207 | 190.18 | 3,361 |
| 200 | 1,912 | 94.30 | 2,962 |
| 250 | 208 | 10.17 | 499 |
| 300 | 2,008 | 122.03 | 8,626 |
| 350 | 5 | 0.16 | 16 |
| 400 | 125 | 10.26 | 1,289 |
| 450 | 85 | 6.50 | 1,034 |
| 600 | 94 | 20.75 | 5,868 |
| 750 | 10 | 5.39 | 2,383 |
Across the eleven sizes our sums come to 480.55 km of pipe and a modelled 26,180 cubic metres, about 26.2 million litres. Those two totals are ours, built row by row from the City’s file; the City publishes neither. The surprise in the table is the 150 mm row. Pipes of that size make up 39.6 percent of the length but only 12.8 percent of the volume, while the 300, 600 and 750 mm pipes together hold 64.5 percent of it. Volume grows with the square of the diameter, and a table makes a Grade 8 student feel that in a way a formula on its own rarely does.
The Python that produces the table reads the nine downloaded pages, skips one placeholder row and adds up length by size before applying the cylinder formula. It uses only the standard library:import json, math
from collections import defaultdict
length_by_size = defaultdict(float)
for offset in range(0, 9000, 1000):
with open(f"mains_{offset}.json", encoding="utf-8") as page:
for feature in json.load(page)["features"]:
pipe = feature["attributes"]
if pipe["DIAMETER"] == 999:
continue # a placeholder, not a size
length_by_size[pipe["DIAMETER"]] += pipe["LENGTH_M"]
total = 0
for size, metres in sorted(length_by_size.items()):
radius = size / 2000 # millimetres to metres, then halved
volume = math.pi * radius ** 2 * metres
total += volume
print(size, round(metres / 1000, 2), "km", round(volume), "m3")
print("modelled volume:", round(total), "cubic metres")
1. Name the model
A main is treated as a cylinder, so its volume is pi times the radius squared times the length. Students write down what that assumes: a perfectly round pipe, full of water, with an inside width equal to the diameter in the file.
2. Fix the units first
The file gives lengths in metres and diameters in what are almost certainly millimetres, since 150, 200 and 300 match standard pipe sizes. Dividing by 2,000 turns a diameter in millimetres into a radius in metres in one step, and students must explain why it is 2,000.
3. Distrust the extremes
Sort the file and odd values appear. 303 rows are shorter than one metre, the longest is over 2.5 km, and each oddity is a question for the student, not a number to quietly delete.
Three things in the file that are not what they seem
One row, OBJECTID 1015, gives a diameter of 999, a value no other pipe shares and almost certainly a placeholder, so we leave it out and say so. 47 rows carry an install year of 1850 and no row has any year from 1851 to 1907; 10 of those 47 are listed as PVC, so the date column for those rows needs checking before anyone draws a history from it. And the Shape__Length column is measured in degrees of latitude and longitude, not metres, so only LENGTH_M is used. Finding those three is the real lesson.
Other columns support a second session. The City is listed as the owner of 7,765 rows, the Region of Waterloo of 194, and 159 are shared. By material, the file lists 4,871 rows of polyvinyl chloride, 1,922 of cast iron and 1,174 of ductile iron. Grouping install years by decade shows cast iron dominating the 1950s and 1960s and PVC taking over from the 1980s, a neat two-way table for MDM4U students. Contains information provided by the City of Waterloo under licence. The file is used under the Waterloo Open Data User Licence, which allows commercial use (licence, dataset page). The City of Waterloo does not endorse this page or our classes.







