Реализовать рассчёт растояний можно с помощью 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