If a player hosts a session, then you can have each other player measure the ping time to that session, and connect the players that have the lowest ping time. If you have lots of sessions, having lots of players ping lots of sessions will scale like N-squared, though, which is not great for large player bases.

If you have multiple data centers, then you can measure ping time to the data centers, and matchmake other players who have the same data center as closest. You can easily set this up by using a single Amazon Elastic Compute Cluster instance per availability zone, for example. This is fairly robust, although it requires that you actually have machine resources around the globe.

If you subscribe to a GeoIP service, you can map the remote IP for each player to a lat/long coordinate, and matchmake players that appear to be close to each other. This requires a good GeoIP service (the cheap ones are not that great,) and players with various firewall/tunnel/VPN situations may get a poor match.

In general, I assume the reason you want to matchmake people based on geography is really because you want to matchmake players to reduce overall ping times, so the first or second options are likely your best bets, as they really do measure ping time, rather than some proxy, such as lat/lon coordinates.