import overpy import math import workers.val def getOSM(lat, lon, distance = 1000): query = """ ( node (around:%i,%f,%f) ["railway"~"tram_stop|station|subway"] [name]; >; node (around:%i,%f,%f) ["highway"="bus_stop"] [name]; >;); out; """ % (distance, lat, lon, distance, lat, lon) api = overpy.Overpass(url="https://overpass.kumi.systems/api/interpreter") res = api.query(query) return res.nodes def cDistance(lat1, lon1, lat2, lon2): lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2]) dila = lat2 - lat1 dilo = lon2 - lon1 diff = 2 * math.asin(math.sqrt(math.sin(dila/2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dilo/2) ** 2)) dis = diff * 6371000 return dis def getStations(nodes, distance = 1000, lat = None, lon = None): unodes = list(set([node.tags["alt_name"].split(",")[0] if "alt_name" in node.tags and len(node.tags["alt_name"].split(",")[0]) > len(node.tags["name"]) else node.tags["name"] for node in nodes])) for node in unodes: for station in workers.val.validateName(node): if lat and lon: idistance = cDistance(station.lat(), station.lon(), lat, lon) if idistance < distance: station.distance = idistance yield station break else: yield station break def findStations(lat, lon, distance = 1000, validate = True): stations = list(getStations(getOSM(lat, lon, distance), distance, lat if validate else None, lon if validate else None)) if validate: return sorted(stations, key = lambda station: station.distance) return stations def worker(lat, lon, distance = 1000, json = False): outtext = """{ "stations": [ """ if json else """ """ for station in findStations(lat, lon, distance): outtext += ",\n" if (json and not outtext.strip()[-1] == "[") else "" station.distance = station.distance or int(cDistance(station.lat(), station.lon(), lat, lon)) outtext += station.json(2, distance = True) if json else station.xml(1, distance = True) outtext += "\n" if not json else "" outtext += """ ] }""" if json else "" return outtext