def home(): cities = tb.read_json('{}/cities.json'.format(informationFolder)) names = tb.read_json('{}/names.json'.format(informationFolder)) return minify(render_template('index.html', title=gettext('Maps - OpenBikes'), cities_file=cities, names_file=names, lang_code='en'))
def map(city): names = tb.read_json('{}/names.json'.format(informationFolder)) centers = tb.read_json('{}/centers.json'.format(informationFolder)) predictions = tb.read_json('{}/predictions.json'.format(informationFolder)) geojson = str(url_for('static', filename='geojson/{}.geojson'.format(city))) return minify(render_template('map.html', city=city, city_name=names[city], center=centers[city], geojson=geojson, predict=predictions[city]))
def api_routing(mode, city, departure, arrival, time, people): ''' Return a list of routes in polyline format. String adresses are not supported because they won't be needed for the mobile apps. Indeed the departure will be the same as the arrival because the mobile apps do not include full trips. Example URL: /routing/mode=takeBike&city=Toulouse& departure=[43.5639677,1.4655774]& arrival=[43.6044328,1.443463]& time=[1442935490355]&people=1 Don't forget to remove all the spaces. ''' if key == tb.read_json('config/keys.json')['api']: situation = { 'city': city, 'departure': eval(departure), 'arrival': eval(arrival), 'time': eval(time), 'people': int(people) } if mode == 'fullTrip': routes = routing.full_trip(situation) elif mode == 'takeBike': routes = routing.take_bike(situation) elif mode == 'dropBike': routes = routing.drop_bike(situation) return jsonify({'routes': routes}) else: return jsonify({'error': 'Wrong API key.'})
def choose(situation, target, distance, mode, stationFirst, nbCandidates=5): """ Choose the best station around the arrival and then define a trip between the departure and the station. """ city = situation["city"] people = situation["people"] time = tb.convert_time(situation["time"]) # Will convert the positions to (lat, lon) if they are textual addresses departure = geography.convert_to_point(city, situation["departure"]) arrival = geography.convert_to_point(city, situation["arrival"]) # Find the close stations with MongoDB stations = [station for station in query.close_points(city, arrival, number=nbCandidates)] # Get the distances to the stations candidates = geography.compute_distances_manual(arrival, stations, distance) # Sort the stations by distance candidates.sort(key=lambda station: station["duration"]) # Find an appropriate solution through the sorted candidates trip = False for candidate in candidates: # Calculate what time it would be when reaching the candidate station forecast = tb.epoch_to_datetime(time + candidate["duration"]) # Extract features from the forecasted time variables = munging.temporal_features(forecast) features = [variables["hour"], variables["minute"], variables["weekday"]] # Check if the prediction is satisfying settings = tb.read_json("common/settings.json") method = eval(settings["learning"]["method"]) # Make a prediction prediction = method.predict(features, target, city, candidate["_id"]) bias = tb.read_json("common/settings.json")["learning"]["bias"] if target == "bikes": bias *= -1 if prediction + bias >= people: stationPosition = list(reversed(candidate["p"])) if stationFirst is False: trip = tb.reshape(mode, departure, stationPosition) else: trip = tb.reshape(mode, stationPosition, departure) break return trip
def update(provider, city, predict): ''' Update the data for a city. ''' # Get the current formatted data for a city try: stations = eval(provider).stations(city) except: return # Update the database if the city can be predicted if predict == 'Yes': insert.city(city, stations) # Save the data for the map geojson = tb.json_to_geojson(stations) tb.write_json(geojson, '{0}/{1}.geojson'.format(geojsonFolder, city)) # Refresh the latest update time updates = tb.read_json('{}/updates.json'.format(informationFolder)) updates[city] = datetime.now().isoformat() tb.write_json(updates, '{}/updates.json'.format(informationFolder))
def turn_by_turn(trip): """ Build a path using the Google Directions API. """ mode = trip["mode"] points = ["{0},{1}".format(point["lat"], point["lon"]) for point in trip["points"]] origin = points[0] destination = points[1] base = "https://maps.googleapis.com/maps/api/directions/json" key = tb.read_json("common/keys.json")["google-distance"] url = "{0}?origin={1}&destination={2}&mode={3}&key={4}".format(base, origin, destination, "walking", key) # Query the API response = get_route(url) trip = tb.load_json(response) return { "mode": mode, "routes": trip["routes"][0]["legs"][0]["steps"], "polyline": trip["routes"][0]["overview_polyline"]["points"], }
def add(stations, size=50): ''' Use the Google Maps Elevation API to add altitudes to a dataframe. Because the API has a limitation this function batches the work into "packages" that are successively send to the API. The size parameter determines the size of the packages. The function starts by looping through the stations and increments a counter. Once the counter has reached the package size then it sends a request to the API and resets the counter. Once it has parsed all the stations it unwraps what the API send back into a list of dictionaries and sends it back. ''' base = 'https://maps.googleapis.com/maps/api/elevation/json?' key = tb.read_json('common/keys.json')['google-elevation'] locations = '' packages = [] counter = 1 for station in stations: locations += '{lat},{lon}|'.format(lat=station['lat'], lon=station['lon']) counter += 1 if counter > size: locations += ';' counter = 1 for loc in locations.split(';'): url = base + 'locations={0}&key={1}'.format(loc[:-1], key) request = tb.query_API(url) data = tb.load_json(request) packages.append(data['results']) # Melt the packages into one list altitudes = [] for package in packages: altitudes.extend(package) # Tidy everything up for database insertion data = [{'name': station[0]['name'], 'lat': station[0]['lat'], 'lon': station[0]['lon'], 'alt': station[1]['elevation']} for station in zip(stations, altitudes)] return data
def api_updates(): ''' Return the list of update times. ''' updates = tb.read_json('{}/updates.json'.format(geojsonFolder)) return jsonify(updates)
def api_predictions(): ''' Return the list of predictions. ''' predictions = tb.read_json('{}/predictions.json'.format(geojsonFolder)) return jsonify(predictions)
from mongo.geo import delete # Define the command line arguments parser = argparse.ArgumentParser(description='Remove a city from the system.') parser.add_argument('provider') parser.add_argument('city') parser.add_argument('country') # Parse the command line arguments parameters = parser.parse_args() provider = parameters.provider city = parameters.city country = parameters.country # Load the information folder path settings = tb.read_json('common/settings.json') informationFolder = settings['folders']['information'] # Load the information files stationsFile = tb.read_json('{}/stations.json'.format(informationFolder)) providersFile = tb.read_json('{}/providers.json'.format(informationFolder)) centersFile = tb.read_json('{}/centers.json'.format(informationFolder)) citiesFile = tb.read_json('{}/cities.json'.format(informationFolder)) namesFile = tb.read_json('{}/names.json'.format(informationFolder)) predictionsFile = tb.read_json('{}/predictions.json'.format(informationFolder)) updatesFile = tb.read_json('{}/updates.json'.format(informationFolder)) # Geographical database try: delete.city(city) except:
def api_stations(): ''' Return the list of countries/cities/stations. ''' stations = tb.read_json('{}/stations.json'.format(geojsonFolder)) return jsonify(stations)
def api_city_stations(city): ''' Return the latest geojson file of a city. ''' stations = tb.read_json('{0}/{1}.geojson'.format(geojsonFolder, city)) return jsonify(stations)
import asyncio from apscheduler.schedulers.asyncio import AsyncIOScheduler from datetime import datetime from collecting.providers import * from mongo.timeseries import insert from common import toolbox as tb settings = tb.read_json('common/settings.json') # Where to save the geojson files geojsonFolder = settings['folders']['geojson'] # Where to place the updated timestamps informationFolder = settings['folders']['information'] # Seconds for rescheduling refresh = settings['collecting']['refresh'] # List of data providers providers = tb.read_json('{}/providers.json'.format(informationFolder)) # Define which cities can be predicted or not predictions = tb.read_json('{}/predictions.json'.format(informationFolder)) def update(provider, city, predict): ''' Update the data for a city. ''' # Get the current formatted data for a city try: stations = eval(provider).stations(city) except: return # Update the database if the city can be predicted if predict == 'Yes': insert.city(city, stations) # Save the data for the map
def api(): cities = tb.read_json('{}/cities.json'.format(informationFolder)) names = tb.read_json('{}/names.json'.format(informationFolder)) return minify(render_template('api.html', title=gettext('API - OpenBikes'), cities_file=cities, stations_file=stations))
parser.add_argument('cityRealName') parser.add_argument('country') parser.add_argument('countryRealName') parser.add_argument('predict') # Parse the command line arguments parameters = parser.parse_args() provider = parameters.provider city = parameters.city cityRealName = parameters.cityRealName country = parameters.country countryRealName = parameters.countryRealName predict = parameters.predict # Load the information folder path settings = tb.read_json('common/settings.json') informationFolder = settings['folders']['information'] # Load the information files stationsFile = tb.read_json('{}/stations.json'.format(informationFolder)) providersFile = tb.read_json('{}/providers.json'.format(informationFolder)) centersFile = tb.read_json('{}/centers.json'.format(informationFolder)) citiesFile = tb.read_json('{}/cities.json'.format(informationFolder)) namesFile = tb.read_json('{}/names.json'.format(informationFolder)) predictionsFile = tb.read_json('{}/predictions.json'.format(informationFolder)) # Get the current information for a city stations = eval(provider).stations(city) # Add the altitudes of every station stations = altitudes.add(stations) # Add the city and the stations to the database
from common import toolbox as tb settings = tb.read_json('common/settings.json') informationFolder = settings['folders']['information'] geojsonFolder = settings['folders']['geojson']
def api_providers(): ''' Return the list of providers/cities. ''' providers = tb.read_json('{}/providers.json'.format(geojsonFolder)) return jsonify(providers)
def update(): city = request.args.get('city', 0, type=str) updates = tb.read_json('{}/updates.json'.format(informationFolder)) update = updates[city] return jsonify({'timestamp': update})
def api_cities(): ''' Return the list of countries/cities. ''' cities = tb.read_json('{}/cities.json'.format(geojsonFolder)) return jsonify(cities)
from os.path import dirname, basename, isfile from common import toolbox as tb import glob # Get all the modules in the current folder modules = glob.glob(dirname(__file__)+"/*.py") # Assign them to __all__ for automatic import __all__ = [basename(f).split('.')[0] for f in modules if isfile(f)] # Open the keys file for the restricted APIs keys = tb.read_json('common/keys.json')
def api_centers(): ''' Return the list of names. ''' centers = tb.read_json('{}/centers.json'.format(geojsonFolder)) return jsonify(centers)
import asyncio from apscheduler.schedulers.asyncio import AsyncIOScheduler import datetime import time from common import toolbox as tb from mongo.timeseries import query from learning import * settings = tb.read_json('common/settings.json') informationFolder = settings['folders']['information'] # Number of days to learn upon timespan = settings['learning']['timespan'] # Number of days for rescheduling refresh = settings['learning']['refresh'] # Regression method method = eval(settings['learning']['method']) # Stations to predict stationsFile = tb.read_json('{}/stations.json'.format(informationFolder)) # Define which cities can be predicted or not predictions = tb.read_json('{}/predictions.json'.format(informationFolder)) def learn(city, station): # Get data from the past 30 days threshold = datetime.datetime.now() - datetime.timedelta(days=timespan) try: dataframe = query.station(city, station, threshold) except: return # Prepare the dataframe for learning dataframe = munging.prepare(dataframe)
def api_names(): ''' Return the list of names. ''' names = tb.read_json('{}/names.json'.format(geojsonFolder)) return jsonify(names)