def pathfind(lat1, long1, lat2, long2): # HERE api limits number of exclusion zones to 20, therefore we have to take extra steps to figure out which # zones we are to give to the api. If more than 20 exclusion zones are in the database, this is done by first # getting the naive path from the Google Maps API, adding only the zones which intersect with the path, and # then getting a path which avoides these zones. This does not guarentee that the path will be free of exclusion # zones, but its the best we can do with these APIs. hdata = hmapalgo(full=True) if len(db) < 20: return polyline.encode(here_get_path(lat1, long1, lat2, long2, hdata)) else: naive_path = google_maps_get_path(lat1, long1, lat2, long2) intersections = get_intersections(naive_path, hdata) return polyline.encode(here_get_path(lat1, long1, lat2, long2, intersections))
def test_encode_official_example_precision(self): e = polyline.encode([ (38.500, -120.200), (40.700, -120.950), (43.252, -126.453) ], 6) self.assertEqual(e, '_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI')
def initialize_sim(fid, timestamp, lat, lon): coords = polyline.encode([(lat, lon)], 5) wind_x, wind_y = get_wind(lat, lon) try: # Make a request to the ForeFire API requests.post( "http://forefire.univ-corse.fr/api/dev/php/forefireAPI.php", data={ 'command': 'init', 'path': fid, 'coords': coords, 'ventX': wind_x, 'ventY': wind_y, 'date': timestamp.strftime('%Y-%m-%dT%H:%M:%SZ') }, headers={'X-Requested-With': 'XMLHttpRequest'}, timeout=1) except requests.exceptions.ReadTimeout: # Request does not return something, so wait for timeout before continuing print("Fire simulation was initialized correctly.") # Compute the number of cycles from fire ignition until now t_diff = datetime.now() - timestamp n_cycles = math.floor(t_diff.total_seconds() / 1200) # Run a propagation of the simulator and return shape return propagate_sim(fid, n_cycles) except requests.exceptions.ConnectionError: print("Server cannot be reached.") return None
def decode(): if (request.method == 'POST'): text = request.form['textboxid'] if (',' in text): text = text.strip() if (';' in text): latlongs = text.split(';') else: latlongs = text.split() arr = [] for i in latlongs: k = i.split(',') arr.append([float(k[0]), float(k[1])]) poly = polyline.encode(arr) return render_template("displayPolyline.html", poly=poly) else: poly = text.strip() try: pings = polyline.decode(poly) latlongs = [] for i in pings: latlongs.append(str(i[0]) + "," + str(i[1])) except: latlongs = ["Polyline inaccurate"] return render_template("displayLatlongs.html", latlongs=latlongs) else: return render_template("home.html")
def _get_route_with_elevation_helper(gps_a, gps_b): """ returns a list of points where each point is a list with lon, lat and altitude (in meters) """ route = get_route(gps_a, gps_b) if route == None: return None encoded_route = polyline.encode(route, geojson=True) body = {"format_in": "encodedpolyline", "geometry": encoded_route} headers = { 'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8', 'Authorization': API_KEY, 'Content-Type': 'application/json; charset=utf-8' } call = requests.post('https://api.openrouteservice.org/elevation/line', json=body, headers=headers) result = json.loads(call.text) if not 'geometry' in result: print(result) return None return result['geometry']['coordinates']
def _generate_requests_for_non_simplified_network(n, osm_tags=all): """ Generates a dictionary describing pairs of nodes for which we need to request directions from Google directions API. For a non-simplified network n :param n: genet.Network :param osm_tags: takes a list of OSM tags to subset the network on, e.g. ['primary', 'secondary', 'tertiary'] :return: """ if osm_tags == all: g = n.modal_subgraph(modes='car') else: g = n.subgraph_on_link_conditions( conditions=[ {'attributes': {'osm:way:highway': {'text': osm_tags}}}, {'modes': 'car'}], how=all, mixed_dtypes=True) simple_paths = simplification._get_edge_groups_to_simplify(g) node_diff = set(g.nodes) - set(itertools.chain.from_iterable(simple_paths)) non_simplified_edges = set(g.out_edges(node_diff)) | set(g.in_edges(node_diff)) all_paths = list(non_simplified_edges) + simple_paths api_requests = {} for path in all_paths: request_nodes = (path[0], path[-1]) api_requests[request_nodes] = { 'path_nodes': path, 'path_polyline': polyline.encode([(n.node(node)['lat'], n.node(node)['lon']) for node in path]), 'origin': n.node(request_nodes[0]), 'destination': n.node(request_nodes[1]) } return api_requests
def get_altitudes(): rounded_coords = set() lat_gain, lon_gain = get_gains() for map_row, lat in enumerate( float_range(config.MAP_START[0], config.MAP_END[0], lat_gain)): row_start_lon = config.MAP_START[1] odd = map_row % 2 != 0 if odd: row_start_lon -= 0.5 * lon_gain for map_col, lon in enumerate( float_range(row_start_lon, config.MAP_END[1], lon_gain)): rounded_coords.add((round(lat, 2), round(lon, 2))) altitudes = dict() try: params = {'locations': 'enc:' + polyline.encode(tuple(rounded_coords))} if hasattr(config, 'GOOGLE_MAPS_KEY'): params['key'] = config.GOOGLE_MAPS_KEY r = requests.get('https://maps.googleapis.com/maps/api/elevation/json', params=params).json() for result in r['results']: coords = (round(result['location']['lat'], 2), round(result['location']['lng'], 2)) altitudes[coords] = result['elevation'] except Exception: for coord in rounded_coords: if hasattr(config, 'ALT_RANGE'): altitudes[coord] = random.uniform(*config.ALT_RANGE) else: altitudes[coord] = random.uniform(300, 400) return altitudes
def test_encode_official_example(self): e = polyline.encode([ (38.500, -120.200), (40.700, -120.950), (43.252, -126.453) ]) self.assertEqual(e, '_p~iF~ps|U_ulLnnqC_mqNvxq`@')
def get_altitudes(coords, precision=3): def chunks(l, n): """Yield successive n-sized chunks from l.""" for i in range(0, len(l), n): yield l[i:i + n] altitudes = dict() if len(coords) > 300: for chunk in tuple(chunks(coords, 300)): altitudes.update(get_altitudes(chunk, precision)) else: try: params = {'locations': 'enc:' + polyline.encode(coords)} if config.GOOGLE_MAPS_KEY: params['key'] = config.GOOGLE_MAPS_KEY r = requests.get('https://maps.googleapis.com/maps/api/elevation/json', params=params).json() for result in r['results']: point = (result['location']['lat'], result['location']['lng']) key = round_coords(point, precision) altitudes[key] = result['elevation'] except Exception: pass return altitudes
def encode_dataset_polyline(data): """get coordinates and encode polyline""" coordinates = () directions = [] for directions in data: direct_poly = [] for line in directions['path']: coordinates = (float(line['lat']), float(line['lon'])) direct_poly.append(coordinates) # add polyline in format of 'main.decodePolylines(directions)' directions.update({'overview_polyline': {'points': polyline.encode(direct_poly, 5)}}) try: data[0]['path'][0]['filename'] except: try: data[0]['path'][0]['filename'] = 'unknown_filename' except: print("No paths were found. Exiting...") exit(1) iowork.save_temp_data(data,'ds_polyline_' + data[0]['path'][0]['filename']) print("Polyline of dataset directions is encoded and saved") return data
async def get_elevation_for_points(settings, points): n = 200 result = [] async with aiohttp.ClientSession() as session: for i in range(0, len(points), n): section_points = points[i:i + n] section_polyline = polyline.encode([(round(point.lat, 6), round(point.lng, 6)) for point in section_points]) r = await session.get( 'https://maps.googleapis.com/maps/api/elevation/json', params={ 'sensor': 'false', 'key': settings['google_api_key'], 'locations': "enc:{}".format(section_polyline) }) elevations = await r.json() if elevations['status'] != 'OK': logging.error(elevations) else: result.extend( (elv['elevation'] for elv in elevations['results'])) return result
def recalculateRouteStats(): collection = db.cleanerRoutes allRoutes = list(collection.find()) i = 0 for route in allRoutes: coorList = [] totalkm = 0.00 j = 1 for datapoint in route['route']: coorList.append([ float(datapoint['coordinates']['latitude']), float(datapoint['coordinates']['longitude']) ]) if j == len(route['route']) - 1: break totalkm += calcDistance(datapoint['coordinates'], route['route'][j]['coordinates'], 1) j += 1 lineString = polyline.encode(coorList) route['lineString'] = lineString startDate = int(float(route['route'][0]['timestamp'])) endDate = int( float(route['route'][len(route['route']) - 1]['timestamp'])) route['startDatetime'] = startDate route['endDatetime'] = endDate route['distance_inkm'] = "%.2f" % totalkm #print route['distance_inkm'] i += 1 collection = db.cleanestRoutes collection.insert(allRoutes)
def generate_requests(n): """ Generates two dictionaries, both of them have keys that describe a pair of nodes for which we need to request directions from Google directions API :param n: genet.Network :return: """ g = n.modal_subgraph(modes='car') simple_paths = list(ox.simplification._get_paths_to_simplify(g)) node_diff = set(g.nodes) - set(itertools.chain.from_iterable(simple_paths)) non_simplified_edges = set(g.out_edges(node_diff)) | set( g.in_edges(node_diff)) all_paths = list(non_simplified_edges) + simple_paths api_requests = {} for path in all_paths: request_nodes = (path[0], path[-1]) api_requests[request_nodes] = { 'path_nodes': path, 'path_polyline': polyline.encode([(n.node(node)['lat'], n.node(node)['lon']) for node in path]), 'origin': n.node(request_nodes[0]), 'destination': n.node(request_nodes[1]) } return api_requests
def encode_polyline_list(self) -> list: """ Not used now. https://developers.google.com/maps/documentation/elevation/overview#Locations :return: """ en = polyline.encode(self.coords_list(), 5, geojson=True) # print(en) return en
def test_encode_multiple_points(self): e = polyline.encode([(40.641, -8.654), (40.641, -8.654), (40.641, -8.656), (40.642, -8.656), (40.642, -8.655), (40.642, -8.655), (40.642, -8.655), (40.642, -8.653), (40.642, -8.653), (40.642, -8.653), (40.641, -8.653), (40.641, -8.654)]) self.assertEqual(e, 'gu`wFnfys@???nKgE??gE?????oK????fE??fE')
def test_encode_multiple_points_precision(self): e = polyline.encode([(40.641, -8.654), (40.641, -8.654), (40.641, -8.656), (40.642, -8.656), (40.642, -8.655), (40.642, -8.655), (40.642, -8.655), (40.642, -8.653), (40.642, -8.653), (40.642, -8.653), (40.641, -8.653), (40.641, -8.654)], 6) self.assertEqual(e, 'o}oolA~ieoO???~{Bo}@??o}@?????_|B????n}@??n}@')
def get_elevation_data(lat_lon_coords, **elvtn_args): key = 'AIzaSyCeoTnfT0MwM8M2sU9amxCZUBxr1Fn_RSQ' path_segments = [] elevation_results = [] df_route = pd.DataFrame(columns=['Lat', 'Lon', 'Elv']) #count = 0 for chunk in chunks(lat_lon_coords, 512): path_segments.append(chunk) path_string = '' for segments in path_segments: #print("outer loop") for lat, lon in segments: path_string = path_string + str(lat) + ',' + str(lon) + '|' #print("inner Loop") path_string = path_string[0:-1] elvtn_args.update({ 'path': path_string, 'samples': str(1), }) """Change out all characters to be encoded with %s""" #Is there any way to request less data? #Polyline encode is lossless, change 5 to lower number? url = ELEVATION_BASE_URL + polyline.encode(chunk, 5) + '&key=' + key #count += 1 #print(count) # print(url) #Downloads each segment of the route one at a time, takes a long time #print("start Download") response = simplejson.load(urllib.request.urlopen(url)) #print("stop Download") # caution will spam terminal #print(response) # Create a dictionary for each results[] object #Only writes elevation to elevation results apparently discards other data. elevation_result = [] for resultset in response['results']: #print(response['results']) #print(resultset['elevation']) elevation_result.append(resultset['elevation']) elevation_results.append(elevation_result) # print(elevation_results) i = 0 for segment_id, segments in enumerate(path_segments): j = 0 for lat, lon in segments: df_route.loc[i] = pd.Series({ 'Lat': lat, 'Lon': lon, 'Elv': elevation_results[segment_id][j] }) j += 1 i += 1 return df_route
def parse_raw_data_to_nametuple(self, run_data, old_gpx_ids, with_gpx=False): run_data = run_data["runrecord"] joyrun_id = run_data["fid"] start_time = run_data["starttime"] end_time = run_data["endtime"] run_points_data = self.parse_content_to_ponits(run_data["content"]) if with_gpx: # pass the track no points if run_points_data: gpx_data = self.parse_points_to_gpx( run_points_data, start_time, end_time ) download_joyrun_gpx(gpx_data, str(joyrun_id)) heart_rate_list = eval(run_data["heartrate"]) if run_data["heartrate"] else None heart_rate = None if heart_rate_list: heart_rate = int(sum(heart_rate_list) / len(heart_rate_list)) # fix #66 if heart_rate < 0: heart_rate = None polyline_str = polyline.encode(run_points_data) if run_points_data else "" start_latlng = start_point(*run_points_data[0]) if run_points_data else None start_date = datetime.utcfromtimestamp(start_time) start_date_local = adjust_time(start_date, "Asia/Shanghai") end = datetime.utcfromtimestamp(end_time) # only for China now end_local = adjust_time(end, "Asia/Shanghai") location_country = None # joyrun location is kind of f*****g strage, so I decide not use it, if you want use it, uncomment this two lines # if run_data["city"] or run_data["province"]: # location_country = str(run_data["city"]) + " " + str(run_data["province"]) d = { "id": int(joyrun_id), "name": "run from joyrun", # future to support others workout now only for run "type": "Run", "start_date": datetime.strftime(start_date, "%Y-%m-%d %H:%M:%S"), "end": datetime.strftime(end, "%Y-%m-%d %H:%M:%S"), "start_date_local": datetime.strftime( start_date_local, "%Y-%m-%d %H:%M:%S" ), "end_local": datetime.strftime(end_local, "%Y-%m-%d %H:%M:%S"), "length": run_data["meter"], "average_heartrate": heart_rate, "map": run_map(polyline_str), "start_latlng": start_latlng, "distance": run_data["meter"], "moving_time": timedelta(seconds=run_data["second"]), "elapsed_time": timedelta( seconds=int((run_data["endtime"] - run_data["starttime"])) ), "average_speed": run_data["meter"] / run_data["second"], "location_country": location_country, "source": "Joyrun", } return namedtuple("x", d.keys())(*d.values())
def direction(r): global pathline global window global userInput2 global endDes window = tkinter.Toplevel() window.config(background="#cfe3fc") window.title("Directions") dist = (r['routes'][0]['distance']) / 1609.344 #in meters dura = (r['routes'][0]['duration']) / 60 #in seconds if r['waypoints'][0]['name'] == '': start = userInput2.get() else: start = r['waypoints'][0]['name'] if r['waypoints'][1]['name'] == '': end = endDes else: end = r['waypoints'][1]['name'] label = tkinter.Label(window, background="#cfe3fc", text=f'Distance: {dist:.2f} miles away') label.grid(sticky="W") label1 = tkinter.Label(window, background="#cfe3fc", text=f'Duration: {dura:.0f} minutes away') label1.grid(sticky="W") label2 = tkinter.Label( window, background="#cfe3fc", text=f'Start Location: {start}') #starting street name label2.grid(sticky="W") label3 = tkinter.Label(window, background="#cfe3fc", text=f'End Location: {end}') #ending street name label3.grid(sticky="W") label4 = tkinter.Label(window, background="#cfe3fc", text="Directions:") label4.grid(sticky="W") ct = 0 steps = r['routes'][0]['legs'][0]['steps'] for s in range(len(steps)): ct += 1 label5 = tkinter.Label( window, background="#cfe3fc", text=f"Step {str(ct)}: {steps[s]['maneuver']['instruction']}") label5.grid(sticky="W") plst = [] dire = r['routes'][0]['legs'][0]['steps'] #list of directions coordinates for d in range(len(dire)): plst.append(tuple(dire[d]["maneuver"]["location"])) #Create a polyline of the direction to display on a map later on pathline = polyline.encode(plst, geojson=True)
def list_properties_rightmove(latitude, longitude, radius, min_bedrooms, min_bathrooms, min_price=0, max_price=0): (lat_min, lon_min, lat_max, lon_max) = boundingBox(latitude, longitude, radius) box = [(lat_min, lon_min), (lat_min, lon_max), (lat_max, lon_max), (lat_max, lon_min), (lat_min, lon_min)] new_home = True payload = { 'apiApplication': 'ANDROID', 'locationIdentifier': 'USERDEFINEDAREA^' + json.dumps({"polylines": polyline.encode(box)}), 'minBedrooms': min_bedrooms } if max_price: payload['maxPrice'] = max_price if min_price: payload['minPrice'] = min_price if new_home: payload['newHome'] = "true" r = requests.get('http://api.rightmove.co.uk/api/sale/find', params=payload, proxies=proxies) for listing in r.json()["properties"]: yield { "id": str(listing["identifier"]), "latitude": listing['latitude'], "longitude": listing['longitude'], "price": int(listing['price']), "url": "http://www.rightmove.co.uk/property-for-sale/property-%d.html" % (listing['identifier']), "description": listing['summary'], "address": listing['address'], "image": listing['photoThumbnailUrl'], "floor_plans": [], "new_home": new_home }
def convert_to_polyline(self, index): gpx = self.get_gpx(index) track_segment = gpx.track.track_segment if (len(track_segment)): line = [(obj.lat, obj.lon) for obj in track_segment] my_polyline = polyline.encode(line) else: return None return my_polyline
def test_get_full_journey(self): services=Calendar.objects.filter(service_id='2#1') time='10:0' prediction_day=0 date='15-08-2019' p=pl.encode([(38.5, -120.2), (40.7, -120.9), (43.2, -126.4)], 5) route={'routes':[{'legs':[{'steps':[ {'distance': {'value': 902}, 'duration': {'value': 669}, 'end_location': {'lat': 53.3188054, 'lng': -6.278130399999999}, 'html_instructions': 'Walk to Harolds Cross, Kenilworth Square North', 'polyline': {'points': p}, 'start_location': {'lat': 53.3229403, 'lng': -6.2773135}, 'travel_mode': 'WALKING'}, {'distance': {'value': 4358}, 'duration': {'value': 1080}, 'end_location': {'lat': 53.3286404, 'lng': -6.2293996}, 'html_instructions': 'Bus towards Crumlin Childrens Hospital - Newgrove Avenue', 'polyline': {'points': p}, 'start_location': {'lat': 53.3187381, 'lng': -6.2780827}, 'transit_details': {'arrival_stop': { 'location': {'lat': 53.3286404, 'lng': -6.2293996}, 'name': 'Ballsbridge, Merrion Road RDS'}, 'arrival_time': {'value': 1565861880}, 'departure_stop': { 'location': {'lat': 53.3187381, 'lng': -6.2780827}, 'name': 'Harolds Cross, Kenilworth Square North'}, 'departure_time': {'value': 1565860800}, 'headsign': 'Crumlin Childrens Hospital - Newgrove Avenue', 'line': {'agencies': [{'name': 'Go-Ahead'}], 'short_name': '18'}, 'num_stops': 16}, 'travel_mode': 'TRANSIT'}, {'distance': { 'value': 8855}, 'duration': {'value': 1696}, 'end_location': {'lat': 53.29017030000001, 'lng': -6.131013}, 'html_instructions': 'Bus towards Loughlinstown Pk', 'polyline': {'points':p}, 'start_location': {'lat': 53.3286404, 'lng': -6.2293996}, 'transit_details': {'arrival_stop': {'location': {'lat': 53.29017030000001, 'lng': -6.131013}, 'name': "George's St Upper"}, 'arrival_time': {'value': 1565864346}, 'departure_stop': { 'location': {'lat': 53.3286404, 'lng': -6.2293996}, 'name': 'Ballsbridge, Merrion Road RDS'}, 'departure_time': {'value': 1565862650}, 'headsign': 'Loughlinstown Pk', 'line': {'agencies': [{'name': 'Dublin Bus'}], 'short_name': '7a'}, 'num_stops': 26}, 'travel_mode': 'TRANSIT'} ]}]}]} #Beacuse we can't create entries using a composit key. This will always return an empty set self.assertEquals(self.test_view_specific.get_full_journeys(route, time, services, prediction_day, date), [])
def get_eta_many_to_many_url(cls, from_latlon_list, to_latlon_list): latlon_list = from_latlon_list + to_latlon_list ids = range(len(latlon_list)) urlholder = """http://{hostport}/table/v1/driving/polyline({coords})?sources={sources}&destinations={destins}""".format( hostport=OSRM_HOSTPORT, coords=polyline.encode(latlon_list, 5), sources=';'.join(map(str, ids[:len(from_latlon_list)])), destins=';'.join(map(str, ids[len(from_latlon_list):]))) return urlholder
def batch_polyline_encode(self): """ Not used. https://developers.google.com/maps/documentation/elevation/overview#Locations :return: """ result = [] for batch in self.create_batch_for_polyline(): result.append(polyline.encode(batch, 5, geojson=True)) return result
def import_streams(cls, client, activity_id, stream_names, timeout=CACHE_ACTIVITIES_TIMEOUT): streams_to_import = list(stream_names) if ("polyline" in stream_names): streams_to_import.append("latlng") streams_to_import.remove("polyline") try: streams = client.get_activity_streams(activity_id, series_type='time', types=streams_to_import) except Exception as e: msg = ("Can't import streams for activity {}:\n{}".format( activity_id, e)) # app.logger.error(msg) return {"error": msg} activity_streams = {name: streams[name].data for name in streams} # Encode/compress latlng data into polyline format if "polyline" in stream_names: if "latlng" in activity_streams: activity_streams["polyline"] = polyline.encode( activity_streams['latlng']) else: return { "error": "no latlng stream for activity {}".format(activity_id) } for s in ["time"]: # Encode/compress these streams if (s in stream_names) and (activity_streams.get(s)): if len(activity_streams[s]) < 2: return { "error": "activity {} has no stream '{}'".format( activity_id, s) } try: activity_streams[s] = cls.stream_encode( activity_streams[s]) except Exception as e: msg = ( "Can't encode stream '{}' for activity {} due to '{}':\n{}" .format(s, activity_id, e, activity_streams[s])) app.logger.error(msg) return {"error": msg} output = {s: activity_streams[s] for s in stream_names} cls.set(activity_id, output, timeout) return output
def build_map_url(coordinates): params = { 'size': '640x640', 'scale': '2', 'maptype': 'terrain', 'path': 'enc:{polyline}'.format(polyline=polyline.encode(coordinates)), 'sensor': 'false', 'language': 'de' } return 'http://maps.googleapis.com/maps/api/staticmap?' + urllib.urlencode(params)
def parse_raw_data_to_nametuple(run_data, old_gpx_ids, with_download_gpx=False): run_data = run_data["data"] run_points_data = [] # 5898009e387e28303988f3b7_9223370441312156007_rn middle keep_id = run_data["id"].split("_")[1] start_time = run_data["startTime"] if run_data.get("vendor", {}).get("source", "") == "Keep" and run_data.get( "rawDataURL" ): raw_data_url = run_data.get("rawDataURL") r = requests.get(raw_data_url) # string strart with `H4sIAAAAAAAA` --> decode and unzip run_points_data = decode_runmap_data(r.text) if with_download_gpx: if str(keep_id) not in old_gpx_ids: gpx_data = parse_points_to_gpx(run_points_data, start_time) download_keep_gpx(gpx_data, str(keep_id)) run_points_data = [[p["latitude"], p["longitude"]] for p in run_points_data] heart_rate = None if run_data["heartRate"]: heart_rate = run_data["heartRate"].get("averageHeartRate", None) # fix #66 if heart_rate and heart_rate < 0: heart_rate = None polyline_str = polyline.encode(run_points_data) if run_points_data else "" start_latlng = start_point(*run_points_data[0]) if run_points_data else None start_date = datetime.utcfromtimestamp(start_time / 1000) tz_name = run_data.get("timezone", "") start_date_local = adjust_time(start_date, tz_name) end = datetime.utcfromtimestamp(run_data["endTime"] / 1000) end_local = adjust_time(end, tz_name) d = { "id": int(keep_id), "name": "run from keep", # future to support others workout now only for run "type": "Run", "start_date": datetime.strftime(start_date, "%Y-%m-%d %H:%M:%S"), "end": datetime.strftime(end, "%Y-%m-%d %H:%M:%S"), "start_date_local": datetime.strftime(start_date_local, "%Y-%m-%d %H:%M:%S"), "end_local": datetime.strftime(end_local, "%Y-%m-%d %H:%M:%S"), "length": run_data["distance"], "average_heartrate": int(heart_rate) if heart_rate else None, "map": run_map(polyline_str), "start_latlng": start_latlng, "distance": run_data["distance"], "moving_time": timedelta(seconds=run_data["duration"]), "elapsed_time": timedelta( seconds=int((run_data["endTime"] - run_data["startTime"]) / 1000) ), "average_speed": run_data["distance"] / run_data["duration"], "location_country": str(run_data.get("region", "")), } return namedtuple("x", d.keys())(*d.values())
def _load_gpx_data(self, gpx): self.start_time, self.end_time = gpx.get_time_bounds() # use timestamp as id self.run_id = int(datetime.datetime.timestamp(self.start_time) * 1000) self.start_time_local, self.end_time_local = parse_datetime_to_local( self.start_time, self.end_time, gpx) if self.start_time is None: raise TrackLoadError("Track has no start time.") if self.end_time is None: raise TrackLoadError("Track has no end time.") self.length = gpx.length_2d() if self.length == 0: raise TrackLoadError("Track is empty.") gpx.simplify() polyline_container = [] heart_rate_list = [] # determinate type and source if gpx.tracks[0].type: self.type = gpx.tracks[0].type if gpx.tracks[0].source: self.source = gpx.tracks[0].source if self.source == "xingzhe": # self.start_time_local = self.start_time self.run_id = gpx.tracks[0].number if gpx.name: self.name = gpx.name else: self.name = self.type + " from " + self.source for t in gpx.tracks: for s in t.segments: try: heart_rate_list.extend([ int(p.extensions[0].getchildren()[0].text) for p in s.points if p.extensions ]) except: pass line = [ s2.LatLng.from_degrees(p.latitude, p.longitude) for p in s.points ] self.polylines.append(line) polyline_container.extend([[p.latitude, p.longitude] for p in s.points]) self.polyline_container = polyline_container # get start point try: self.start_latlng = start_point(*polyline_container[0]) except: pass self.polyline_str = polyline.encode(polyline_container) self.average_heartrate = (sum(heart_rate_list) / len(heart_rate_list) if heart_rate_list else None) self.moving_dict = self._get_moving_data(gpx)
def getMapquestlevations(API, locations=""): encoded = polyline.encode(locations, 6) encoded = encoded.replace("\\", "\\\\") url = r"http://open.mapquestapi.com/elevation/v1/profile?key={0}&shapeFormat=cmp6&latLngCollection={1}".format( API, encoded) response = simplejson.load(urllib.request.urlopen(url)) elevationprofile = response["elevationProfile"] elevations = [] for pt in elevationprofile: elevations.append(pt["height"]) return elevations
def get_path(direction_data): """ get distance from google directions api response, the unit for this field is meter """ path = [] for r in json.loads(direction_data)['routes'][0]['legs']: for i in r['steps']: path += polyline.decode(i['polyline']['points']) return polyline.encode(path)
def append(self, other): """Append other track to self.""" self.end_time = other.end_time self.length += other.length self.moving_dict["distance"] += other.moving_dict["distance"] self.moving_dict["moving_time"] += other.moving_dict["moving_time"] self.moving_dict["elapsed_time"] += other.moving_dict["elapsed_time"] self.polylines[0].extend(other.polylines[0]) self.polyline_str = polyline.encode(self.polylines[0]) self.file_names.extend(other.file_names) self.special = self.special or other.special
def get_altitude(point): try: params = {'locations': 'enc:' + polyline.encode((point,))} if config.GOOGLE_MAPS_KEY: params['key'] = config.GOOGLE_MAPS_KEY r = requests.get('https://maps.googleapis.com/maps/api/elevation/json', params=params).json() altitude = r['results'][0]['elevation'] except Exception: altitude = random_altitude() return altitude
def _add_shape_to_route(route, direction, shape, stop_distances, stats): encoded_shape = polyline.encode(shape, stop_distances) direction['stop_distances'] = encoded_shape['fixed_indexes'] if encoded_shape['points'] in route['shapes']: logging.error('Duplicate shape encoding for route {}'.format(route['name'])) else: route['shapes'].append(encoded_shape['points']) direction['shape_i'] = len(route['shapes']) - 1 stats['shapes'] += 1 stats['points'] += len(shape) stats['dropped_points'] += encoded_shape['num_dropped_points'] stats['bytes'] += len(encoded_shape['points'])
def group_by_segments(rides): segments = defaultdict(list) for ride in rides: points = polyline.decode(ride.route.path) for i in range(0, len(points)-1): src = points[i] dst = points[i+1] segments[_sorted_tuple((src, dst))].append(ride) logger.info("Got {} distinct segments".format(len(segments))) return [(polyline.encode([src, dst]), rides) for (src, dst), rides in segments.items()]
def test_encode_multiple_points_precision(self): e = polyline.encode([ (40.641, -8.654), (40.641, -8.654), (40.641, -8.656), (40.642, -8.656), (40.642, -8.655), (40.642, -8.655), (40.642, -8.655), (40.642, -8.653), (40.642, -8.653), (40.642, -8.653), (40.641, -8.653), (40.641, -8.654) ], 6) self.assertEqual(e, 'o}oolA~ieoO???~{Bo}@??o}@?????_|B????n}@??n}@')
def test_encode_multiple_points(self): e = polyline.encode([ (40.641, -8.654), (40.641, -8.654), (40.641, -8.656), (40.642, -8.656), (40.642, -8.655), (40.642, -8.655), (40.642, -8.655), (40.642, -8.653), (40.642, -8.653), (40.642, -8.653), (40.641, -8.653), (40.641, -8.654) ]) self.assertEqual(e, 'gu`wFnfys@???nKgE??gE?????oK????fE??fE')
def get_stream_data(activity_id): key = "J:{}".format(activity_id) stream_data = cache.get(key) if not stream_data: stream_names = ['time', 'latlng', 'distance', 'altitude'] streams = client.get_activity_streams(activity_id, types=stream_names) stream_data = {name: streams[name].data for name in streams} if 'latlng' in stream_data: stream_data["polyline"] = ( polyline.encode(stream_data.get('latlng')) ) cache.set(key, stream_data, cache_timeout) return stream_data
def import_streams(activity_id, stream_names): streams_to_import = list(stream_names) if ("polyline" in stream_names): streams_to_import.append("latlng") streams_to_import.remove("polyline") try: streams = client.get_activity_streams(activity_id, series_type='time', types=streams_to_import) except Exception as e: app.logger.debug(e) return {"error": str(e)} activity_streams = {name: streams[name].data for name in streams} if ("polyline" in stream_names) and ("latlng" in activity_streams): activity_streams["polyline"] = polyline.encode( activity_streams['latlng']) return {s: activity_streams[s] for s in stream_names}
def get_static(conn=None, max_attempts=3, size='800x600', **kwargs): conn = conn or requests base_url = 'https://maps.googleapis.com/maps/api/staticmap?' try: markers = '&markers={}'.format(kwargs.pop('markers')) except KeyError: markers = '' # convert coordinates into polyline if not already try: path = kwargs.get('path', '') substring = re.search('{}(.*){}'.format('enc:', '\|'), path).group() data = json.loads(substring.split('enc:')[1]) encoded = polyline.encode(data) path.replace(substring, 'enc:{}|'.format(encoded)) params['path'] = path except NameError: raise AttributeError('Unable to create polyline encoding because ' 'polyline module is not installed') except (AttributeError, IndexError, JSONDecodeError): pass # one url to bring them all and in the darkness bind them params = '&'.join(['{}={}'.format(k,v) for k,v in iteritems(kwargs)]) url = '{b}{p}&size={s}{m}'.format(b=base_url, s=size, p=params, m=markers) url = url[:2048].rsplit('|', 1)[0] #to keep url within 2048 char max limit for x in range(max_attempts): try: res = conn.get(url) res.raise_for_status() break except HTTPError: pass # raise if all attempts fail res.raise_for_status() img = Image.open(BytesIO(res.content)) return img
def test_a_variety_of_precisions(self): """uses a generator to create a variety of lat-lon's across the global and tests a range of precision settings from 4 to 8""" def generator(): while True: coords = [] for i in range(2, randint(4, 10)): lat, lon = uniform(-180.0, 180.0), uniform(-180.0, 180.0) coords.append((lat, lon)) yield coords patience = 3 # seconds. waypoints, okays = 0, 0 g = generator() start = time.time() while time.time() < start + patience: precision = randint(4, 8) wp = next(g) waypoints += len(wp) poly = polyline.encode(wp, precision) wp2 = polyline.decode(poly, precision) if wp == wp2: okays += len(wp2) else: for idx, _ in enumerate(wp): dx, dy = abs(wp[idx][0] - wp2[idx][0]), abs(wp[idx][1] - wp2[idx][1]) if dx > 10 ** -(precision - 1) or dy > 10 ** -(precision - 1): print("idx={}, dx={}, dy={}".format(idx, dx, dy)) else: okays += 1 assert okays == waypoints print("encoded and decoded {0:.2f}% correctly for {1} waypoints @ {2} wp/sec".format( 100 * okays / float(waypoints), waypoints, round(waypoints / patience, 0)))
import numpy as np import polyline # London bounding box N = 51.691874116909894 E = 0.3340155643740321 S = 51.28676016315085 W = -0.5103750689005356 num_coords = 1000 coords = zip( np.random.uniform(S, N, [num_coords]), np.random.uniform(W, E, [num_coords]) ) if __name__ == "__main__": for x in range(500): polyline.encode(coords)
def path(self): return polyline.encode([(x.lat, x.lng) for x in self.waypoints])
def test_rounding_py3_match_py2(self): e = polyline.encode([ (36.05322, -112.084004), (36.053573, -112.083914), (36.053845, -112.083965)]) self.assertEqual(e, 'ss`{E~kbkTeAQw@J')
def test_encode_single_point_precision(self): e = polyline.encode([ (40.641, -8.653) ], 6) self.assertEqual(e, 'o}oolAnkcoO')
def _get_encoded_polyline(gpx_points, is_hq): very_small = {True: 0.000005, False: 0.00002}[is_hq] points = [] for point in gpx_points: points.append((float(point['lat']), float(point['lon']))) return polyline.encode(points, very_small=very_small)
def test_encode_single_point_rounding(self): e = polyline.encode([ (0, 0.000006), (0, 0.000002) ]) self.assertEqual(e, '?A?@')
def _get_encoded_points(self): return polyline.encode(self._points)
def thumbnailUrlMapbox(ptlist): token = keysnpwds['MapBoxApiKey'] l = urllib.quote_plus(polyline.encode(ptlist)) url = 'https://api.mapbox.com/styles/v1/mapbox/outdoors-v11/static/path(%s),pin-s-a(%f,%f),pin-s-b(%f,%f)/auto/130x110?access_token=%s'%(l,ptlist[0][1],ptlist[0][0],ptlist[-1][1],ptlist[-1][0],token) return url
import time from math import ceil import haversine import polyline from math import ceil from polyline_generator import Polyline a = Polyline((47.1706378, 8.5167405), (47.1700271, 8.518072999999998), 100) print(a.points) print('Walking polyline: ', a.polyline) print('Encoded level: ','B'*len(a.points)) print('Initialted with speed: ', a.speed, 'm/s') print('Walking time: ', ceil(sum([haversine.haversine(*x)*1000/a.speed for x in a.walk_steps()])), ' sec.') generated_polyline = [] while a.points[-1] != a.get_pos()[0]: pos = a.get_pos() generated_polyline += pos print(pos) time.sleep(0.1) else: print("We have reached our destination.") print(polyline.encode(generated_polyline)) print('Encoded level: ','B'*len(generated_polyline)) print('Verify at: ', 'https://developers.google.com/maps/documentation/utilities/polylineutility')
def encode_polyline(features): """Encode and iterable of features as a polyline """ points = list(read_points(features)) latlon_points = [(x[1], x[0]) for x in points] return polyline.encode(latlon_points)
def compose_locations_param(points): param = polyline.encode(points) return 'enc:'+param
def combine_polylines(self, points): return polyline.encode(points)
def test_encode_single_point(self): e = polyline.encode([ (40.641, -8.653) ]) self.assertEqual(e, 'gu`wFf`ys@')