Finding The Middle When Two Points Don't Behave Nicely
I spent about six months dealing with a routing problem where our system kept assigning deliveries to a location that existed only on paper. Two address points on opposite sides of a river, and the midpoint calculation was placing the "middle" point right in the water. That's the real world of halfway-between-address mapping — it sounds straightforward until you hit the edge cases that break every naive implementation. The basic idea is simple enough: you have two geographic coordinates, and you want a third coordinate that sits equidistant between them. Most people reach for the arithmetic mean — average the latitudes, average the longitudes, call it done. That works fine if your two points are within a few kilometers of each other on a flat plane. It falls apart quickly after that.
The Curious Case Of Halfway Between Two Addresses Mapping The Mystery Of The Inbetween Zone
Here's what actually happens when you try to build this. You take Address A, geocode it to get a lat/lon pair. You take Address B, geocode it the same way. Now you need to find the point between them. The approach depends entirely on what you mean by "between." If you're working with a GIS platform like QGIS, there's a built-in midpoint tool under Vector > Geometry Tools. You feed it two points and it returns the geometric middle. In Python, you'd use something like geopy's Distance.from_geopoint or just calculate it manually with the haversine formula. The haversine approach uses great-circle distance, which accounts for the Earth's curvature. It's the standard for anything over roughly 100 kilometers. The pitfall nobody warns you about is that "halfway" is not a single thing. There are at least four different interpretations, and they produce different results:
- Geometric midpoint — straight line through the Earth's interior, or projected onto a 2D map. Fast, but geographically meaningless at scale.
- Great-circle midpoint — halfway along the shortest surface path. This is what most people actually want, and it's what geopy gives you by default.
- Driving-distance midpoint — halfway along the actual road network. This requires a routing API like OSRM, Valhalla, or Google Routes. It's the most useful for logistics but the most computationally expensive.
- Time-distance midpoint — halfway in terms of travel time, not distance. Two points equally far apart by road might take very different driving times if one route is a highway and the other is a winding country road.
I ran into this specifically last year when a client needed a midpoint between a warehouse in Newark and a distribution center in Pittsburgh. The great-circle midpoint landed somewhere near Cleveland. The driving-distance midpoint, calculated through OSRM's car profile, was actually closer to Philadelphia because the I-76 corridor is faster than the mountain routes through western Pennsylvania. The difference was about 140 kilometers. For a delivery scheduling system, that's the difference between a viable depot and one that adds twenty minutes to every route. For the road-network approach, here's the practical workflow. First, you geocode both addresses to WGS84 coordinates. Then you snap them to the nearest road segment — geocoded points often land on driveways or in parking lots, which will throw off your routing. Use a snapping tolerance of about 50 meters. After that, query a routing engine for the full path and distance. Divide the total by two, then interpolate along the polyline at that cumulative distance. The OSRM table API can do this in a single request if you send both points as start and end, but it won't return the midpoint directly. You'll need to extract the geometry from the route response and use shapely or geojsonio to interpolate at the halfway mark. In QGIS, the process is more visual. Load your two point layers, use the Geometry Generator to create a line between them, then use the Extract Vertices tool and pick the middle vertex. It's not precise for long distances because QGIS works in the project's CRS, so make sure you're using a suitable equal-area projection or switch to the Virtual Layer with ST_LineLocatePoint functions. For most urban-scale work, the default WGS84 Web Mercator projection is fine and the error is negligible.
Get the Full Details

There are tools that wrap all of this up if you don't want to code it. GeoMedia has a midpoint function. MapInfo does too. For a quick one-off, online calculators like gcmap.com or movable-type.co.uk/scripts/latlong.html will give you the great-circle midpoint in seconds. But none of them handle road-network interpolation, and that's where most real projects get stuck. Another thing that bites people: datum shifts. If one address is geocoded to WGS84 and the other comes from an old survey in NAD27, your midpoint will be off by anywhere from a few meters to several hundred depending on the location. Always reproject both points to the same datum before calculating. In Python, pyproj handles this with a single Transform call. And finally, the case where it just doesn't work. If your two points are on opposite sides of the globe — say, Auckland and Madrid — the concept of a midpoint breaks down because there are infinitely many great-circle paths between them, each with a different midpoint. In practice, routing engines pick the shorter path, but for antipodal or near-antipodal points you should flag this as a special case rather than silently returning a result that may not match user expectations.
I keep a small utility script for this now. It takes two addresses, geocodes them, snaps to roads, calculates both the great-circle and driving-distance midpoints, and outputs a GeoJSON with both points plus the route geometry. About forty lines of Python. Takes roughly three seconds to run per pair on a standard API rate limit. Saved me from having to rebuild this logic every time a new client asked for it.