Реализовать рассчёт растояний можно с помощью Graphhopper, основанного на данных OpenStreetMap:
https://graphhopper.com/api/1/docs/routing/#output - здесь документация, вам нужен параметр 
paths[0].distance (второй сверху)
Про города и области с помощью этого же сервиса можно это реализовать. В запросе нужно передавать параметр 
points_encoded=false (
документация), тогда на выходе в поле 
points получите список точек маршрута. Затем можно находить, в каком городе / какой области находится каждая точка, используя обратный геокодер в составе Nominatim (опять же, основанного на данных из OSM). Документация по нему: 
wiki.openstreetmap.org/wiki/Nominatim#Reverse_Geocoding