def graph_to_animation(self): quasi_centroid = self.polygon_area.representative_point() self.animation = folium.Map(location=(quasi_centroid.y, quasi_centroid.x), zoom_start=14, tiles='OpenStreetMap') p = shapely.ops.cascaded_union([pl for pl in self.polygon_area]) point_list = list(zip(*p.exterior.coords.xy)) folium.PolyLine(locations=[(y, x) for (x, y) in point_list], fill_color="green", weight=1, color='green').add_to(self.animation) edges_s = sorted(self.net.graph.edges(data=True), key=lambda x: x[2]['event']) nodes_s = sorted(self.net.graph.nodes(data=True), key=lambda x: x[1]['event']) last_event = max(edges_s[-1][2]['event'], nodes_s[-1][1]['event']) e_coords = [] e_times = [] for e in edges_s: e_coords.append([list(self.net.graph.nodes()[e[0]]['pos']), list(self.net.graph.nodes()[e[1]]['pos'])]) e_times.append(1530744263666 + e[2]['event'] * 86400000) # FIXME starting time is just a random moment features_edges = { 'type': 'Feature', 'geometry': { 'type': 'MultiLineString', 'coordinates': e_coords, }, 'properties': { 'times': e_times, } } n_coords = [] n_times = [] for n in nodes_s: n_coords.append([n[1]['pos'], n[1]['pos']]) n_times.append(1530744263666 + n[1]['event'] * 86400000) # the only way I found to plot the nodes is pretend they are # one-point lines features_nodes = { 'type': 'Feature', 'geometry': { 'type': 'MultiLineString', 'coordinates': n_coords, }, 'properties': { 'times': n_times, 'style': { 'color': 'red', 'width': 20 } } } plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', 'features': [features_edges, features_nodes]}, transition_time=500, auto_play=False).add_to(self.animation)
def create_map_trajectories( list_trajectories, mapper_centroid, path_html='../PRIVATE DATA/output/example_application_debug_master.html' ): lines = [] for traj in list_trajectories: dict_line = {} for id_cell, timestep in traj: coord_centroid = mapper_centroid[id_cell] if 'coordinates' not in dict_line: dict_line['coordinates'] = [[ coord_centroid[1], coord_centroid[0] ]] dict_line['dates'] = [timestep] dict_line['color'] = 'red' else: dict_line['coordinates'].append( [coord_centroid[1], coord_centroid[0]]) dict_line['dates'].append(timestep) lines.append(dict_line) features = [{ "type": "Feature", "geometry": { "type": "LineString", "coordinates": line["coordinates"], }, "properties": { "times": line["dates"], "style": { "color": '#%06x' % random.randint(0, 0xFFFFFF), "weight": 5, "opacity": 0.7 }, }, } for line in lines] # create map Folium, Bologna(lat,long) map_time_traj = folium.Map(location=[44.4992192, 11.2616459], zoom_start=10) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='PT1M', add_last_point=True, auto_play=False, loop=True, max_speed=1, transition_time=2000, loop_button=True, time_slider_drag_update=True).add_to(map_time_traj) map_time_traj.save(path_html) return map_time_traj
def create_map(): ''' Function for creating a map :return: None ''' points = points_feat.create_points(flask_path) # points = points_feat.create_points(main_path) FEATURES = points['features'] print(FEATURES) points_COORDINATES = points['coordinates'] DEF_TIME = points['set-time'] folium_map = folium.Map(location=[40.738, -73.98], zoom_start=12, tiles="CartoDB dark_matter") # MiniMap plugin minimap = plugins.MiniMap() folium_map.add_child(minimap) # Fullscreen plugin plugins.Fullscreen(position='topright', title='Expand me', title_cancel='Exit me', force_separate_button=True).add_to(folium_map) # Timestamp plugin plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': FEATURES }, period='PT4H', add_last_point=True).add_to(folium_map) COORDINATES = [] for c in points_COORDINATES: newlst = [c[1], c[0]] aqi = pollution.get_air_data(newlst, DEF_TIME)[0] / 2.5 newlst.append(aqi) COORDINATES.append(newlst) print(COORDINATES) heat_map = plugins.HeatMap(COORDINATES, radius=50) heat_map.layer_name = 'Air Quality' folium_map.add_child(heat_map) folium_map.add_child(folium.LayerControl()) print('> Done.') folium_map.save("../NY_MAP/templates/my_map.html")
def make_folium(coordinates, data, start_date, save_file="../results/map.html", center=[27.700769, 85.300140], zoom=7, tiles="http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"): m = folium.Map( location=center, zoom_start=zoom, tiles=tiles, attr='...', ) print(len(data)) print(len(data[0])) date = start_date features = [] for data_single in data: for coordinate, coor_data in zip(coordinates, data_single): feature = { 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [coordinate[0], coordinate[1]] }, 'properties': { 'time': date.__str__(), 'style': { 'color': 'red' }, 'icon': 'circle', 'iconstyle': { 'fillColor': "red", 'fillOpacity': 0.8, 'stroke': 'true', 'radius': coor_data } } } features.append(feature) date += datetime.timedelta(days=1) print(features[0]) #,features[76],features[77]) print(len(features)) plugins.TimestampedGeoJson(features, period='P1D', duration='P1D', transition_time=1000, auto_play=False).add_to(m) m.save(save_file)
def get_route_animations(lines): features = [{'type': 'Feature', 'geometry': {'type': 'LineString', 'coordinates': line['coordinates']}, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': 3, 'opacity': 0.75}} } for line in lines] return plugins.TimestampedGeoJson( {'type': 'FeatureCollection', 'features': features}, period='PT1M', add_last_point=False, auto_play=False, loop=True)
def plot_traj_timestamp_geo_json(df_, label_datetime='datetime', label_lat='lat', label_lon='lon', tiles='cartodbpositron'): features = create_geojson_features_line(df_, label_datetime) print('creating folium map') map_ = create_folium_map( default_location=[df_[label_lat].mean(), df_[label_lon].mean()], tiles=tiles) print('Genering timestamp map') plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT1M', add_last_point=True).add_to(map_) return map_
def make_map(map_type = 'dynamic', features = None, options = dict()): ''' Creates a folium map based on already created features and a set of options for customization Parameters ------- map_type: String 'dynamic' 'dynamic' or 'static'. Whether is a dinamic map or not features: JSON iterable None JSON format for folium map features options: dict dict() Returns ------- Folium.Map object ''' m = Map( location=options['location'], tiles=options['tiles'], zoom_start=options['zoom'], ) if map_type == 'static': return m plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='P'+options['period'], add_last_point=True, auto_play=False, loop=False, max_speed=5, loop_button=True, date_options='YYYY/MM/DD', time_slider_drag_update=True, duration='P'+options['period'] ).add_to(m) return m
def map_features(features): m = folium.Map(location=(40.730610, -73.935242), zoom_start=10, tiles="Stamen Toner") plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='P1Y', duration="P1Y", add_last_point=True, auto_play=False, loop=False, max_speed=0.5, loop_button=True, date_options='YYYY', time_slider_drag_update=True).add_to(m) return m
def _add_time_layer(data, time_column, period='P1D', duration='P1D', date_options=' YYYY-MM-DD', transition_time=1000, radius=7, fill_color=None, color_column=None, color_list=None, color_min_val=None, color_max_val=None, line_opacity=0.7, fill_opacity=0.7): """Add and style a temporal (animation) layer\n data: Geodataframe\n time_column: Date/timestamp column. period: Used to construct the array of available times starting from the first available time. Format: ISO8601 Ex: ‘P1M’ 1/month, ‘P1D’ 1/day, ‘PT1H’ 1/hour, and ‘PT1M’ 1/minute\n duration: Period of time which the features will be shown on the map after their time has passed. If None, all previous times will be shown. Format: ISO8601 Duration ex: ‘P1M’ 1/month, ‘P1D’ 1/day, ‘PT1H’ 1/hour, and ‘PT1M’ 1/minute\n date_options: Format to be displayed in the map.\n transition_time: The duration in ms of a transition from between timestamps.\n radius: The size of the points.\n fill_color: Specifies a fixed color to be used for all the geometries\n color_column: Field to be used to calculate the color ramp.\n color_list: List of colors to build the color ramp ex ['green','white', 'red'] otherwise sets a red to blue ramp as a default.\n color_min_val: set a minimum range for the color ramp. Used when limiting the color range.\n color_max_val: Set a maximum range for the color ramp. Used when limiting the color range.\n opacity: The layer opacity set between 0 and 1.\n \nexample:\n m = add_map(data= gdf)\n add_time_layer(data= gdf, time_column= 'datetime', color_column= 'color_values').add_to(m)\n add_map_controls(m) m.save('my_temporal_map.html') #Used when needing to plot large amounts of data which notebook can't handle""" df = data.copy() colors = add_colormap(df, color_column=color_column, color_list=color_list, color_min_val=color_min_val, color_max_val=color_max_val, fill_color=fill_color) df = _stringify_date(df) df['time'] = df[time_column] df['icon'] = 'circle' try: df_json = df.to_json() json_data = json.loads(df_json) except TypeError: df_json = _cast_object_to_string(df).to_json() json_data = json.loads(df_json) for feature, color in zip(json_data['features'], colors): feature['properties']['style'] = { 'fillColor': color, 'color': color, 'fillOpacity': fill_opacity } feature['properties']['iconstyle'] = { 'fillColor': color, 'stroke': 'True', 'radius': radius, 'opacity': line_opacity } output = plugins.TimestampedGeoJson(json_data, transition_time=1000, loop=True, auto_play=True, add_last_point=True, period=period, duration=duration, min_speed=0.1, max_speed=10, loop_button=True, date_options='YYYY-MM-DD HH:mm:ss', time_slider_drag_update=True) return (output)
def make_map(save_url='app/templates/earthquakes.html'): df = pd.read_csv('https://earthquake.usgs.gov/earthquakes/' 'feed/v1.0/summary/2.5_month.csv') features = [{ 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [r['longitude'], r['latitude']], }, 'properties': { 'time': r['time'][0:-1], 'popup': (f"<strong>Time:</strong> {r['time']}<br>" f"<strong>Place:</strong> {r['place']}<br>" f"<strong>Magnitude:</strong> {r['mag']} {r['magType']}<br>" f"<strong>Depth:</strong> {r['depth']}<br>"), 'icon': 'circle', 'iconstyle': { 'fillOpacity': 0.5, 'stroke': 0, 'radius': r['mag'] * 2.5 }, } } for i, r in df.iterrows()] m = folium.Map( tiles='CartoDBpositron', # zoom_start=1, # no_wrap=True, min_zoom=1.5, max_zoom=5, ) # add faults with open("data/PB2002_boundaries.json", "r") as read_file: fault_features = json.load(read_file) folium.GeoJson( { 'type': 'FeatureCollection', 'features': fault_features['features'], }, style_function=lambda x: { 'color': 'red', 'weight': 0.5, }).add_to(m) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='PT6H', # six hour time_slider_drag_update=True, duration='PT12H', date_options='YYYY-MM-DD HH UTC').add_to(m) folium.plugins.Fullscreen( position='topright', force_separate_button=True, ).add_to(m) m.save(save_url)
def folium_timespan_geojson_html(schedule, satname): timespan_map = folium.Map(location=[-26, 132], tiles='OpenStreetMap', zoom_start=3) #lines=[] polygons = [] lines = [] polygons = [] #polygontuples = () colorindex = 0 colorlut = getredtoblack(len(schedule) + 1) for i in schedule: pointlist = [] polygonlist = [] #timeslist = [] datelist = [] for x in i['Orbit line']: pointlist.append([x['lon2'], x['lat2']]) datelist.append(str(x['time']).replace(" ", "T")) # folium expects a time for each point - could use iterate for len of points and time period to get times per point - or add to dict from original function which uses time lines.append({ 'coordinates': pointlist, 'dates': datelist, 'color': str(colorlut[colorindex]), 'weight': 2 }) datelist = [] for x in i['Swath polygon']: #polygonlist.append([x['lat2'],x['lon2']]) pointtuple = (x['lon2'], x['lat2']) polygonlist.append(pointtuple) datelist.append(str(x['time']).replace(" ", "T")) polygons.append({ 'coordinates': [(tuple(polygonlist), )], 'dates': datelist, 'color': str(colorlut[colorindex]), 'weight': 2 }) colorindex = colorindex + 1 features = [ { 'type': 'Feature', 'geometry': { 'type': 'MultiPolygon', 'coordinates': polygon['coordinates'], }, 'properties': { 'times': polygon['dates'], 'style': { 'color': polygon['color'], 'opacity': 0.1, 'weight': polygon['weight'] if 'weight' in polygon else 5 } } } #for line in lines for polygon in polygons ] featureslines = [{ 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'dash-array': '[4]', 'weight': line['weight'] if 'weight' in line else 5 } } } for line in lines #for polygon in polygons ] for featureline in featureslines: features.append(featureline) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT1M', duration=None, add_last_point=False, auto_play=True, transition_time=1, time_slider_drag_update=True).add_to(timespan_map) plugins.Fullscreen(position='topright', title='Expand me', title_cancel='Exit me', force_separate_button=True).add_to(timespan_map) timespan_map ''' colorindex = 0 for i in schedule: pointlist = [] polygonlist = [] #timeslist = [] datelist = [] for x in i['Orbit line']: pointlist.append([x['lon2'], x['lat2']]) datelist.append(str(x['time']).replace(" ","T")) # folium expects a time for each point - could use iterate for len of points and time period to get times per point - or add to dict from original function which uses time polygons.append({'coordinates': pointlist, 'dates': datelist, 'color': colorlut[colorindex],'weight': 2}) colorindex = colorindex +1 datelist = [] for x in i['Swath polygon']: #polygonlist.append([x['lat2'],x['lon2']]) pointtuple = (x['lon2'],x['lat2']) polygonlist.append(pointtuple) datelist.append(str(x['time']).replace(" ","T")) polygons.append({'coordinates': [(tuple(polygonlist),)], 'dates': datelist, 'color': colorlut[colorindex],'weight': 2}) #colorindex = colorindex +1 #print(polygonlist) features = [ { 'type': 'Feature', 'geometry': { #'type': 'LineString', #'coordinates': line['coordinates'], 'type': 'MultiPolygon', 'coordinates': polygon['coordinates'], }, 'properties': { #'times': line['dates'], #'style': { # 'color': line['color'], # 'weight': line['weight'] if 'weight' in line else 5 'times': polygon['dates'], 'style': { 'color': polygon['color'], 'weight': polygon['weight'] if 'weight' in polygon else 5 } } } #for line in lines for polygon in polygons ] #print(features) #plugins.TimestampedGeoJson({ # 'type': 'FeatureCollection', # 'features': features, #}, period='PT1M', duration=None,add_last_point=False, auto_play=True, transition_time=1).add_to(timespan_map) style_function = lambda x: {'fillColor': '#00ffff'} gj = folium.GeoJson({ 'type': 'FeatureCollection', 'features': features, }, style_function=style_function) #gj.add_child(folium.GeoJsonTooltip(fields=["Satellite :", "Sensor :", \ # "Orbit height :", "Orbit number :", \ # "Acquisition of Signal Local :", "Acquisition of Signal UTC :", \ # "Loss of Signal UTC :", "Transit time :", \ # "Node :"])) gj.add_to(timespan_map) #timespan_map.add_child(folium.GeoJsonTooltip(fields=["Satellite :", "Sensor :", \ # "Orbit height :", "Orbit number :", \ # "Acquisition of Signal Local :", "Acquisition of Signal UTC :", \ # "Loss of Signal UTC :", "Transit time :", \ # "Node :"])) plugins.Fullscreen( position='topright', title='Expand me', title_cancel='Exit me', force_separate_button=True ).add_to(timespan_map) ''' foliumtimespanhtml = os.path.join( output_path, satname + "." + ground_station_name + ".timespan.map.html") timespan_map.save(foliumtimespanhtml)
def showMap(): app = QtWidgets.QApplication(sys.argv) # print(len(routeName)) colors = ['red', 'blue', 'green', 'black'] lines = [] timePos = 0 if len(routeName) == 2: coordName = pathCoord[routeName[0] + ' -> ' + routeName[1]] # print(len(coordName)) for j in range(len(coordName)): lines.append({ 'coordinates': coordName[j], 'dates': [timeSet[timePos], timeSet[timePos + 1]], 'color': colors[j] }) timePos += 1 else: coordName = [] for i in range((len(routeName) - 1)): coordName.append(pathCoord[routeName[i] + ' -> ' + routeName[i + 1]]) for j in range(len(coordName)): for k in range(len(coordName[j])): lines.append({ 'coordinates': coordName[j][k], 'dates': [timeSet[timePos], timeSet[timePos + 1]], 'color': colors[k] }) timePos += 1 # print(lines) features = [{ 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': line['weight'] if 'weight' in line else 5 } } } for line in lines] m = folium.Map(location=[37.4500597, 127.1276783], tiles="OpenStreetMap", zoom_start=17) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT1M', add_last_point=True).add_to(m) data = io.BytesIO() m.save(data, close_file=False) w = QtWebEngineWidgets.QWebEngineView() w.setHtml(data.getvalue().decode()) w.resize(1280, 720) w.show() sys.exit(app.exec_())
def test_timestamped_geo_json(): coordinates = [[[[lon - 8 * np.sin(theta), -47 + 6 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)], [[lon - 4 * np.sin(theta), -47 + 3 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)]] for lon in np.linspace(-150, 150, 7)] data = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [0, 0], }, "properties": { "times": [1435708800000 + 12 * 86400000] } }, { "type": "Feature", "geometry": { "type": "MultiPoint", "coordinates": [[lon, -25] for lon in np.linspace(-150, 150, 49)], }, "properties": { "times": [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 49) ] } }, { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [[lon, 25] for lon in np.linspace(-150, 150, 25)], }, "properties": { "times": [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 25) ] } }, { "type": "Feature", "geometry": { "type": "MultiLineString", "coordinates": [[[lon - 4 * np.sin(theta), 47 + 3 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)] for lon in np.linspace(-150, 150, 13)], }, "properties": { "times": [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 13) ] } }, { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": coordinates, }, "properties": { "times": [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 7) ] } }, ], } m = folium.Map([47, 3], zoom_start=1) tgj = plugins.TimestampedGeoJson(data) m.add_child(tgj) m._repr_html_() out = m._parent.render() # Verify the imports. assert ('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/' 'jquery.min.js"></script>') in out assert ('<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/' '1.10.2/jquery-ui.min.js"></script>') in out assert ('<script src="https://rawgit.com/nezasa/' 'iso8601-js-period/master/iso8601.min.js"></script>') in out assert ('<script src="https://rawgit.com/socib/Leaflet.' 'TimeDimension/master/dist/leaflet.timedimension.min.js">' '</script>') in out assert ('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/' 'libs/highlight.js/8.4/styles/default.min.css" />') in out assert ( '<link rel="stylesheet" href="http://apps.socib.es/Leaflet.' 'TimeDimension/dist/leaflet.timedimension.control.min.css" />') in out # Verify that the script is okay. tmpl = Template(""" {{this._parent.get_name()}}.timeDimension = L.timeDimension({period:"{{this.period}}"}); {{this._parent.get_name()}}.timeDimensionControl = L.control.timeDimension({ position: 'bottomleft', autoPlay: {{'true' if this.auto_play else 'false'}}, playerOptions: { transitionTime: {{this.transition_time}}, loop: {{'true' if this.loop else 'false'}}} }); {{this._parent.get_name()}}.addControl({{this._parent.get_name()}}.timeDimensionControl); var {{this.get_name()}} = L.timeDimension.layer.geoJson( L.geoJson({{this.data}}), {updateTimeDimension: true,addlastPoint: true} ).addTo({{this._parent.get_name()}}); """) # noqa assert ''.join(tmpl.render(this=tgj).split()) in ''.join(out.split()) bounds = m.get_bounds() assert bounds == [[-53.0, -158.0], [50.0, 158.0]], bounds
def makemap(lst): geomap = folium.Map([23.75, 121], zoom_start=8, tiles="cartodbpositron") folium.TileLayer('stamenterrain').add_to(geomap) folium.TileLayer('openstreetmap').add_to(geomap) colors = ["#FFFFFF", "#FFAAAA", "#FF6666","#FF6666", "#FF6666","#FF6666", "#FF0000","#FF0000","#FF0000","#FF0000"] cm = branca.colormap.LinearColormap(colors, vmin=0, vmax=1).to_step(len(colors)) cm.caption = 'EI value' geomap.add_child(cm) sp,*pred = lst dfsp = pd.read_csv("../output_csv/combine/{}.csv".format(sp)) tl1 = get_list(dfsp,2) if len(pred) == 1: pred1 = pd.read_csv("../output_csv/combine/{}.csv".format(pred[0])) tl2 = get_list(pred1,1,ref=True) tl3 = [] elif len(pred) == 2: pred1 = pd.read_csv("../output_csv/combine/{}.csv".format(pred[0])) pred2 = pd.read_csv("../output_csv/combine/{}.csv".format(pred[1])) tl2 = get_list(pred1,1,ref=True) tl3 = get_list(pred2,3,ref=True) else: tl2 = tl3 = [] features = add_station(dfsp,sp) FC = tl1 + tl2 + tl3 + features plugins.TimestampedGeoJson( { 'type': 'Feature', 'features': FC }, period='P1M', duration='P15D', auto_play=False, loop=False, loop_button=True, date_options='YYYY/MM', ).add_to(geomap) plugins.Fullscreen(position='topright', force_separate_button=True).add_to(geomap) plugins.MiniMap().add_to(geomap) plugins.MeasureControl(primary_length_unit='kilometers', secondary_length_unit='meters', primary_area_unit='hectares', secondary_area_unit='sqmeters').add_to(geomap) formatter = "function(num) {return L.Util.formatNum(num, 3) + ' º ';};" plugins.MousePosition( position='bottomleft', separator=' | ', empty_string='NaN', lng_first=True, num_digits=20, prefix='Coordinates:', lat_formatter=formatter, lng_formatter=formatter ).add_to(geomap) geomap.add_child(folium.LayerControl(position="topleft")) # return geomap geomap.save('../html/{}.html'.format(sp))
def test_timestamped_geo_json(self): data = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [0,0], }, "properties": { "times": [1435708800000+12*86400000] } }, { "type": "Feature", "geometry": { "type": "MultiPoint", "coordinates": [[lon,-25] for lon in np.linspace(-150,150,49)], }, "properties": { "times": [1435708800000+i*86400000 for i in np.linspace(0,25,49)] } }, { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [[lon,25] for lon in np.linspace(-150,150,25)], }, "properties": { "times": [1435708800000+i*86400000 for i in np.linspace(0,25,25)] } }, { "type": "Feature", "geometry": { "type": "MultiLineString", "coordinates": [[[lon-4*np.sin(theta),47+3*np.cos(theta)]\ for theta in np.linspace(0,2*np.pi,25)]\ for lon in np.linspace(-150,150,13)], }, "properties": { "times": [1435708800000+i*86400000 for i in np.linspace(0,25,13)] } }, { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [[[[lon-8*np.sin(theta),-47+6*np.cos(theta)]\ for theta in np.linspace(0,2*np.pi,25)], [[lon-4*np.sin(theta),-47+3*np.cos(theta)]\ for theta in np.linspace(0,2*np.pi,25)]]\ for lon in np.linspace(-150,150,7)], }, "properties": { "times": [1435708800000+i*86400000 for i in np.linspace(0,25,7)] } }, ], } mape = folium.Map([47, 3], zoom_start=1) mape.add_plugin(plugins.TimestampedGeoJson(data)) mape._build_map()
def geojson_visualization(df): """This function animate the shortest path using Timestamped GeoJson. Parameters ---------- df : data.frame, longtitude an latitude for each node in the shortest path. Returns ------- an interactive map drawing the shortest path. """ m = folium.Map( location=[43.61032245, 3.8966295], tiles="cartodbpositron", zoom_start=13) lines = [ { 'coordinates': [ [df.loc[i, 'lon'], df.loc[i, 'lat']], [df.loc[i+1, 'lon'], df.loc[i+1, 'lat']], ], 'dates': [ pd.to_datetime(df.loc[i,'time'], unit='m', origin=pd.Timestamp('2020-05-19')).__str__(), pd.to_datetime(df.loc[i+1,'time'], unit='m', origin=pd.Timestamp('2020-05-19')).__str__() ], 'color': 'red' } for i in range(len(df)-1) ] features = [ { 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': 4 }, 'icon': 'circle', 'iconstyle':{'radius' : 1} # 'iconUrl': "https://www.google.fr/imgres?imgurl=https%3A%2F%2Fstatic.thenounproject.com%2Fpng%2F13133-200.png&imgrefurl=https%3A%2F%2Fthenounproject.com%2Fterm%2Fpedestrian%2F162693%2F&tbnid=Ih-71qXZVedo9M&vet=12ahUKEwiP0vvAkK7pAhUXMRoKHbSzD7oQMygAegUIARDlAQ..i&docid=MBEwWPNEKbzbsM&w=200&h=200&q=icon%20pedestrian&ved=2ahUKEwiP0vvAkK7pAhUXMRoKHbSzD7oQMygAegUIARDlAQ", # 'iconSize': [16, 16]}, # 'popupTemplate' : "<strong>{pedestrian}</strong>" } } for line in lines ] plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', 'features': features, }, period='PT1H', # duration = 'PT1M', add_last_point=True).add_to(m) m.save('geojson_visualization.html') return m
}, 'style': { 'weight': 1 } } } for point in time_data_points] from folium import plugins plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', 'features': features }, period='P1Y', add_last_point=True, auto_play=False, loop=False, max_speed=1, loop_button=True, date_options='YYYY', time_slider_drag_update=True, duration='P1Y').add_to(yearly_geospatial_map) yearly_geospatial_map monthly_geospatial_map = folium.Map(location=[40.698027, -73.932098], tiles="CartoDB positron", zoom_control=False) time_data_points = []
def main(): """ ********************************************* Extract and clean data from nyc open data ********************************************* """ APP_TOKEN = app_token() base_url = "https://data.cityofnewyork.us/resource/h9gi-nx95.json?$$app_token={}".format( APP_TOKEN) url = base_url + "{}" cnt_url = base_url + "{}{}" # select , where where_inj = "&$where=number_of_cyclist_injured>0.0&$limit=50000" where_kill = "&$where=number_of_cyclist_killed>0.0" inj_df = pd.read_json(url.format(where_inj)) killed_df = pd.read_json(url.format(where_kill)) def dt(date, time): date = pd.to_datetime(date).dt.date time = pd.to_datetime(time).dt.time return date, time # so frustrating. NYC open data changed columns from "accident" to "crash" killed_df.crash_date, killed_df.crash_time = dt(killed_df.crash_date, killed_df.crash_time) inj_df.crash_date, inj_df.crash_time = dt(inj_df.crash_date, inj_df.crash_time) killed_df = killed_df.rename(columns={ 'crash_date': 'accident_date', 'crash_time': 'accident_time' }) inj_df = inj_df.rename(columns={ 'crash_date': 'accident_date', 'crash_time': 'accident_time' }) df = (pd.concat([ inj_df, killed_df ]).drop(columns='location').drop_duplicates().reset_index(drop=True)) df.vehicle_type_code1 = df.vehicle_type_code1.apply( lambda x: str(x).upper()) df.vehicle_type_code2 = df.vehicle_type_code2.apply( lambda x: str(x).upper()) df['Accident Year'] = df.accident_date.apply(lambda x: x.year) df['Accident Month'] = df.accident_date.apply(lambda x: x.month) df['Accident Hour'] = df.accident_time.apply(lambda x: x.hour) def create_df(group): return (df.groupby(group).collision_id.count().reset_index().rename( columns={'collision_id': 'Number of Accidents'})) """ ********************************************* Create figures for month and hour data ********************************************* """ crash_mo_yr = create_df(['Accident Year', 'Accident Month']) crash_hr = create_df('Accident Hour') crash_mo_hr = create_df(['Accident Month', 'Accident Hour']) killed_df['accident_year'] = killed_df.accident_date.apply( lambda x: x.year) killed_df['accident_month'] = killed_df.accident_date.apply( lambda x: x.month) killed_df['accident_hr'] = killed_df.accident_time.apply(lambda x: x.hour) mo_fig = px.area(crash_mo_yr, x="Accident Month", y="Number of Accidents", animation_frame="Accident Year", range_y=[0, 800], range_x=[1, 12]) mo_fig.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 1000 mo_fig.layout.title = "Bicycle Accidents by Month for Each Year" pio.write_html(mo_fig, file="app/static/mo_fig.html", auto_play=False) hr_fig = px.area(crash_mo_hr, x="Accident Hour", y="Number of Accidents", animation_frame="Accident Month", range_y=[0, 400], range_x=[0, 23]) hr_fig.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 1000 hr_fig.layout.title = "Bicycle Accidents by Hour For Each Month" pio.write_html(hr_fig, file="app/static/hr_fig.html", auto_play=False) """ ********************************************* Extract data from citibike files - all trips ********************************************* """ fdir = './agg_trip' agg_files = os.listdir(fdir) agg_df = pd.read_csv(fdir + '/' + agg_files[0]).iloc[:, [0, 1]] for i in range(1, len(agg_files)): agg_df = agg_df.append( pd.read_csv(fdir + '/' + agg_files[i]).iloc[:, [0, 1]]) agg_df.Date = pd.to_datetime(agg_df.Date).dt.date agg_df = agg_df.rename(columns={ 'Trips over the past 24-hours (midnight to 11:59pm)': 'Number of Trips' }) agg_df = agg_df.sort_values('Date') fig = px.line(agg_df, x='Date', y='Number of Trips', title="Number of CitiBike Trips by Day", hover_name='Date') pio.write_html(fig, file="app/static/fig.html", auto_play=False) """ ********************************************* Using 9/25/2019 to map common citibike routes ********************************************* """ high_day = pd.read_csv('./app/static/high_day.csv') coord092519 = high_day[[ 'start station name', 'start station id', 'start station latitude', 'start station longitude', 'end station name', 'end station id', 'end station latitude', 'end station longitude' ]].copy() coord092519['id'] = (coord092519['start station name'] + coord092519['end station name']) coord092519 = coord092519.groupby([ 'start station name', 'start station id', 'start station latitude', 'start station longitude', 'end station name', 'end station id', 'end station latitude', 'end station longitude' ]).id.count().reset_index() coord092519['filt'] = coord092519.apply( lambda x: 'y' if x['start station name'] == x['end station name'] else '', axis=1) coord092519 = coord092519[coord092519.filt != 'y'].reset_index(drop=True) cohort = coord092519[coord092519.id >= 4] cohort = cohort.rename(columns={'id': 'count'}) cohort['id'] = cohort['start station id'].apply( str) + '-' + cohort['end station id'].apply(str) routes = pd.read_csv('./app/static/backup_route_file.csv') routes = routes[ routes.geojson != '{"message":"Too Many Requests"}'].reset_index( drop=True) cohort_df = pd.merge(cohort, routes[['id', 'geojson']], on='id', how='inner') cohort_df = cohort_df[['geojson']].drop_duplicates() geojson = list(cohort_df.geojson) gjson = [] for i in range(len(geojson)): gjson.append( json.loads(geojson[i])['routes'][0]['geometry']['coordinates']) for i in gjson: for j in i: j.reverse() """ ********************************************* mapping the accidents ********************************************* """ loc_df = df[[ 'borough', 'latitude', 'longitude', 'on_street_name', 'off_street_name', 'accident_date' ]].copy() loc_df = loc_df[(pd.isna(loc_df.latitude) == False) & (loc_df.latitude != 0) & (loc_df.longitude != 0)] loc_df.on_street_name = loc_df.on_street_name.str.strip() loc_df.off_street_name = loc_df.off_street_name.str.strip() loc_df.accident_date = loc_df.accident_date.apply(str) loc_df['lat_lon_list'] = loc_df.apply(lambda x: [x.longitude, x.latitude], axis=1) loc_df = loc_df.sort_values('accident_date').reset_index(drop=True) intersect_df = loc_df.copy() intersect_df[ 'intersection'] = intersect_df.on_street_name + ';' + intersect_df.off_street_name intersect_df.intersection = intersect_df.intersection.apply( lambda x: ' & '.join(sorted(x.split(';'))) if pd.isna(x) == False else x) dang_int = (intersect_df.groupby( ['borough', 'intersection'])['accident_date'].count().reset_index().sort_values( 'accident_date', ascending=False).rename( columns={'accident_date': 'Number of Bike Accidents'})) # For the table dang_int_viz = (dang_int[dang_int['Number of Bike Accidents'] >= 10].copy( ).reset_index(drop=True).rename(columns={ 'borough': 'Borough', 'intersection': 'Intersection' })) for i in dang_int_viz.index: Crash( dang_int_viz.iloc[i].Borough, dang_int_viz.iloc[i].Intersection).create_map().save( 'app/static/crash_maps/' + dang_int_viz.iloc[i].Borough + dang_int_viz.iloc[i].Intersection.replace(' ', '_') + '.html') dang_int_viz.Intersection = dang_int_viz.apply( lambda x: '<a href={} target="iframe_map">{}</a>'.format( '../static/crash_maps/' + x.Borough + x.Intersection.replace( ' ', '_') + '.html', x.Intersection), axis=1) html = """<table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th>Borough</th> <th>Intersection</th> <th>Number of Bike Accidents</th> </tr> </thead> <tbody> """ for i in dang_int_viz.index: html = (html + '<tr><td>' + dang_int_viz.iloc[i].Borough + '</td><td>' + dang_int_viz.iloc[i].Intersection + '</td><td>' + str(dang_int_viz.iloc[i]['Number of Bike Accidents']) + '</td></tr>') html = html + "</tbody></table>" html = BeautifulSoup(html, "lxml") html.body.insert( 0, BeautifulSoup('<link rel="stylesheet" href="/static/style.css">', "lxml")) with open('app/static/crash_table.html', 'w') as f: f.write(str(html)) lat_lon = intersect_df[['intersection', 'lat_lon_list']].copy() lat_lon.lat_lon_list = lat_lon.lat_lon_list.apply( lambda x: str(round(x[0], 5)) + ';' + str(round(x[1], 5))) lat_lon = lat_lon.drop_duplicates().reset_index(drop=True) lat_lon.lat_lon_list = lat_lon.lat_lon_list.apply( lambda x: [float(i) for i in x.split(';')]) for i in lat_lon.index: lat_lon.lat_lon_list[i].reverse() dang_int = pd.merge(dang_int, lat_lon, on='intersection', how='left') dang_int.to_csv('app/static/dang_int.csv', index=False) dang_int_10 = ( dang_int[(dang_int['Number of Bike Accidents'] >= 10) & (dang_int['Number of Bike Accidents'] < 15)].reset_index( drop=True)) dang_int_15 = ( dang_int[(dang_int['Number of Bike Accidents'] >= 15) & (dang_int['Number of Bike Accidents'] < 20)].reset_index( drop=True)) dang_int_20 = ( dang_int[dang_int['Number of Bike Accidents'] >= 20].reset_index( drop=True)) features = [{ 'type': 'Feature', 'geometry': { 'type': 'MultiPoint', 'coordinates': list(loc_df.lat_lon_list), }, 'properties': { 'times': list(loc_df.accident_date), 'icon': 'circle', 'iconstyle': { 'fillColor': 'red', 'fillOpacity': 0.5, 'stroke': 'false', 'radius': 5 }, 'style': { 'weight': 0.5 } } }] """ ********************************************* Getting the bike lanes and formatting the data ********************************************* """ bike_lanes = pd.read_json('./app/static/Bicycle Routes.geojson') bl_prot_json = [] bl_stand_json = [] for i in bike_lanes.index: if bike_lanes.iloc[i].features['properties']['facilitycl'] == 'I': for j in range( len(bike_lanes.iloc[i].features['geometry'] ['coordinates'])): bl_prot_json.append( bike_lanes.iloc[i].features['geometry']['coordinates'][j]) else: for j in range( len(bike_lanes.iloc[i].features['geometry'] ['coordinates'])): bl_stand_json.append( bike_lanes.iloc[i].features['geometry']['coordinates'][j]) for i in bl_prot_json: for j in i: j.reverse() for i in bl_stand_json: for j in i: j.reverse() """ ********************************************* Creating the map and interactive features ********************************************* """ nyc_map = folium.Map(location=[40.735, -73.95], zoom_start=11.5, tiles=None) folium.TileLayer('cartodbdark_matter', control=False).add_to(nyc_map) # Add bike lanes folium.PolyLine(bl_prot_json, weight=1, opacity=0.9, color='lime').add_to( folium.FeatureGroup(name='Protected Bike Lanes').add_to(nyc_map)) folium.PolyLine(bl_stand_json, weight=1, opacity=0.9, color='yellow').add_to( folium.FeatureGroup( name='Non-Protected Bike Lanes').add_to(nyc_map)) # Add citibike routes folium.PolyLine(gjson, weight=1, opacity=0.2).add_to( folium.FeatureGroup(name='Commonly Used Citibike Routes', overlay=False).add_to(nyc_map)) # Add Dangerous intersections data over10 = folium.FeatureGroup(name='Intersections w/10-14 Accidents', overlay=False) for i in dang_int_10.index: over10.add_child( folium.Marker( dang_int_10.lat_lon_list[i], tooltip=(dang_int_10.intersection[i] + ':\t' + str(dang_int_10['Number of Bike Accidents'][i]) + ' Accidents'), icon=folium.Icon(color='red', prefix='fa', icon='fas fa-bicycle'))) over15 = folium.FeatureGroup(name='Intersections w/15-19 Accidents', overlay=False) for i in dang_int_15.index: over15.add_child( folium.Marker( dang_int_15.lat_lon_list[i], tooltip=(dang_int_15.intersection[i] + ':\t' + str(dang_int_15['Number of Bike Accidents'][i]) + ' Accidents'), icon=folium.Icon(color='red', prefix='fa', icon='fas fa-bicycle'))) over20 = folium.FeatureGroup(name='Intersections w/20 or More Accidents', overlay=False) for i in dang_int_20.index: over20.add_child( folium.Marker( dang_int_20.lat_lon_list[i], tooltip=(dang_int_20.intersection[i] + ':\t' + str(dang_int_20['Number of Bike Accidents'][i]) + ' Accidents'), icon=folium.Icon(color='red', prefix='fa', icon='fas fa-bicycle'))) nyc_map.add_child(over10) nyc_map.add_child(over15) nyc_map.add_child(over20) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='P1M', add_last_point=True, auto_play=True, loop=False, max_speed=2, loop_button=True, date_options='YYYY-MM-DD', time_slider_drag_update=True, duration='P1M').add_to(nyc_map) folium.LayerControl().add_to(nyc_map) nyc_map.save('app/static/map_nyc.html') """ ********************************************* Bike crash causes ********************************************* """ # Decided not to use the below for now. Could use it in the future... bike_list = ['BIKE', 'BICYCLE', 'E-BIK', 'BICYCLE', 'BYCIC'] cause_df = df[((pd.isna(df.contributing_factor_vehicle_3) == True) & ((df.vehicle_type_code1.isin(bike_list) == True) | (df.vehicle_type_code2.isin(bike_list) == True)))] cause_df = cause_df[(cause_df.vehicle_type_code1.isin(bike_list) == False) | (cause_df.vehicle_type_code2.isin(bike_list) == False)] def bike_cause(x): if x.vehicle_type_code1 in bike_list: return x.contributing_factor_vehicle_1 else: return x.contributing_factor_vehicle_2 def veh_cause(x): if x.vehicle_type_code1 not in bike_list: return x.contributing_factor_vehicle_1 else: return x.contributing_factor_vehicle_2 cause_df['bike_cause'] = cause_df.apply(bike_cause, axis=1) cause_df['veh_cause'] = cause_df.apply(veh_cause, axis=1) # remove Unspecified from dataset. Not useful bike_cause_df = (cause_df.groupby( 'bike_cause').collision_id.count().reset_index().sort_values( 'collision_id', ascending=False).head(15).reset_index(drop=True)) bike_cause_df = bike_cause_df[bike_cause_df.bike_cause != 'Unspecified'] veh_cause_df = (cause_df.groupby( 'veh_cause').collision_id.count().reset_index().sort_values( 'collision_id', ascending=False).head(15).reset_index(drop=True)) veh_cause_df = veh_cause_df[veh_cause_df.veh_cause != 'Unspecified']
folium.Marker( location=[28.389777, 77.0555867], icon=folium.Icon(color="blue",icon="home", prefix='fa') ).add_to(base_map3) features = [ { 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': line['weight'] if 'weight' in line else 3 } } } for line in lines+lines2 ] plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', 'features': features, }, period='PT1M', add_last_point=False).add_to(base_map3) base_map3.render()
def make_map(qry_params, map_params, save_path=save_path): qry_params['format'] = 'csv' qry_params['limit'] = 20000 # TODO: flash a warning message r = requests.get('https://earthquake.usgs.gov/fdsnws/event/1/query', params=qry_params) df = pd.read_csv(StringIO(r.text)) features = [{ 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [r['longitude'], r['latitude']], }, 'properties': { 'time': r['time'][0:-1], 'popup': (f"<strong>Time:</strong> {r['time']}<br>" f"<strong>Place:</strong> {r['place']}<br>" f"<strong>Magnitude:</strong> {r['mag']} {r['magType']}<br>" f"<strong>Depth:</strong> {r['depth']}<br>"), 'icon': 'circle', 'iconstyle': { 'fillOpacity': 0.5, 'stroke': 0, 'radius': r['mag'] * 2.5 }, } } for i, r in df.iterrows()] m = folium.Map( tiles='CartoDBpositron', world_copy_jump=True, zoom_start=1.5, min_zoom=1.5, max_zoom=5, ) # add faults with open("data/PB2002_boundaries.json", "r") as read_file: fault_features = json.load(read_file) folium.GeoJson( { 'type': 'FeatureCollection', 'features': fault_features['features'], }, style_function=lambda x: { 'color': 'red', 'weight': 0.5, }).add_to(m) plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period=map_params['period'], time_slider_drag_update=True, duration=map_params['duration'], date_options='YYYY-MM-DD HH UTC').add_to(m) folium.plugins.Fullscreen( position='topright', force_separate_button=True, ).add_to(m) m.save(str(save_path)) return True
'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': line['weight'] if 'weight' in line else 3 }, 'icon': 'circle', 'fillOpacity': .4, 'iconstyle': { 'fillOpacity': .4, 'stroke-opacity': .4, } } } for line in lines] #add the TimestampedGeoJson to the Map geoj = plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT5S') m.add_child(geoj) # Save map m.save("map.html")
def GenerateGeoAnimation(TPS): TPS.columns = [ 'time', 'segmentID', 'AVG_Spd_GP', 'AVG_Spd_HOV', 'AVG_Vol_GP', 'AVG_Vol_HOV', 'TrafficIndex_GP', 'TrafficIndex_HOV' ] TPS['time'] = TPS['time'].apply(lambda x: datetime.fromtimestamp( datetime.timestamp(x)).astimezone().isoformat()) segment = GetSegmentGeo() # merge TPS with segment data segment.rename(columns={"segmentid": "segmentID"}, inplace=True) data = segment.merge(TPS, on=['segmentID'], how='left') data['TrafficIndex_GP'] = data['TrafficIndex_GP'].fillna(1) data['TrafficIndex_HOV'] = data['TrafficIndex_HOV'].fillna(1) scaled_data = data scaled_data['TrafficIndex_GP'] = data['TrafficIndex_GP'] * 100 scaled_data['TrafficIndex_HOV'] = data['TrafficIndex_HOV'] * 100 temporal_data = segment.merge(TPS, on=['segmentID'], how='left') temporal_data['TrafficIndex_GP'] = temporal_data['TrafficIndex_GP'] * 100 temporal_data['TrafficIndex_HOV'] = temporal_data['TrafficIndex_HOV'] * 100 features = [] for _, line in temporal_data.iterrows(): route = line['geometry'] features.append( Feature(geometry=route, properties={ "TrafficIndex_GP": float(line['TrafficIndex_GP']), "name": line["name"], "times": [line['time']] * len(line['geometry'].coords), "style": { "color": colormap(line['TrafficIndex_GP']) if not np.isnan(line['TrafficIndex_GP']) else 'green' } })) m = folium.Map([47.673650, -122.260540], zoom_start=10, tiles="cartodbpositron") plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT1H', add_last_point=False, max_speed=10, min_speed=0.1, transition_time=1000, loop_button=True, time_slider_drag_update=True).add_to(m) colormap.add_to(m) STREAMLIT_STATIC_PATH = os.path.join(os.path.dirname(st.__file__), 'static') for filename in glob.glob(os.path.join(STREAMLIT_STATIC_PATH, 'ani*')): os.remove(filename) filename_with_time = f'ani_{time.time()}.html' map_path = os.path.join(STREAMLIT_STATIC_PATH, filename_with_time) open(map_path, 'w').write(m._repr_html_()) # st.markdown('Below is the traffic performance score by segments:' + dt_string) st.markdown("Please use **Chrome** for best visualization quality.") st.markdown( f'<iframe src="/{filename_with_time}" ; style="width:100%; height:480px;"> </iframe>', unsafe_allow_html=True)
def setupMap(processed1, processed2): points1 = processed1[1] points1A = processed1[2] time1 = processed1[0] points2 = processed2[1] points2A = processed2[2] time2 = processed2[0] # Create map at the first point of the second file m = folium.Map(location=points2A[1], zoom_start=15) # add lines for each point, but slightly transparent so we can see them both folium.vector_layers.PolyLine(points2A, color='red', weight=2.5, opacity=.5).add_to(m) folium.vector_layers.PolyLine(points1A, color='blue', weight=2.5, opacity=.5).add_to(m) # time and points are in sublists of 3 items each with 1 element of overlap. newpoints2 = list(divide_points(points2)) newtimes2 = list(divide_points(time2)) newtimes1 = list(divide_points(time1)) newpoints1 = list(divide_points(points1)) # # Create the line segments lines = [] for i in range(0, len(newpoints1)): seg = { 'coordinates': newpoints1[i], 'dates': newtimes1[i], 'color': 'blue' } lines.append(seg) for i in range(0, len(newpoints2)): seg = { 'coordinates': newpoints2[i], 'dates': newtimes2[i], 'color': 'red' } lines.append(seg) # print(lines) # Features of GeoJSON map overlay features = [{ 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': line['coordinates'] }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': (line['weight'] if 'weight' in line else 3) }, 'icon': 'circle', 'fillOpacity': .4, 'iconstyle': { 'radius': 2, 'fillOpacity': .4, 'stroke-opacity': .2 }, } } for line in lines] # add the TimestampedGeoJson to the Map geoj = plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='PT5S') m.add_child(geoj) # Save map m.save('map.html')
'type': 'LineString', 'coordinates': line['coordinates'], }, 'properties': { 'times': line['dates'], 'style': { 'color': line['color'], 'weight': line['weight'] if 'weight' in line else 10 } } } for line in lines] plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features, }, period='PT24H', add_last_point=True).add_to(m) m # If you look at above map, # 1. yellow lines mark the trip distance. # 2. Trip starts at pickup location , start of yellow color line and stops where the blue marker gets created. # 3. Black Marker denotes exact location of LA Guardia International Airport. If you click on black marker ,its location name popups. # 4. Most of the trips to airport are to or from Manhattan. # Hope you loved it :) # # <a id='explore'></a> # # ### Explore Data
fill=True, fill_color='#07131d').add_to(archivos[mapa]) #circulo = folium.Circle( # radius=1000, # location=[lapromedio, lopromedio], # popup='Sector', # color='crimson', # fill=False, #) #circulo.add_to(archivos[mapa]) #sectores[mapa].add_to(archivos[mapa]) #m.save("rendiciones/poligono"+file+".html") plug = plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', }, period='PT1M', add_last_point=True) #plug.add_to(archivos[mapa]) legend_html = ''' <div style="position: fixed; top: 50px; right: 50px; width: 20%; height: 10%; border:2px solid grey; z-index:9999; font-size:14px; "> Datos Generales <br> Entregados : ''' + str( len(lista_nueva) ) + ''' <i class="fa fa-map-marker fa-2x" style="color:red"></i> </div> '''
def test_timestamped_geo_json(): coordinates = [[[[lon-8*np.sin(theta), -47+6*np.cos(theta)] for theta in np.linspace(0, 2*np.pi, 25)], [[lon-4*np.sin(theta), -47+3*np.cos(theta)] for theta in np.linspace(0, 2*np.pi, 25)]] for lon in np.linspace(-150, 150, 7)] data = { 'type': 'FeatureCollection', 'features': [ { 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [0, 0], }, 'properties': { 'times': [1435708800000+12*86400000] } }, { 'type': 'Feature', 'geometry': { 'type': 'MultiPoint', 'coordinates': [[lon, -25] for lon in np.linspace(-150, 150, 49)], }, 'properties': { 'times': [1435708800000+i*86400000 for i in np.linspace(0, 25, 49)] } }, { 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': [[lon, 25] for lon in np.linspace(-150, 150, 25)], }, 'properties': { 'times': [1435708800000+i*86400000 for i in np.linspace(0, 25, 25)], 'style': { 'color': 'red' }, }, }, { 'type': 'Feature', 'geometry': { 'type': 'MultiLineString', 'coordinates': [[[lon-4*np.sin(theta), 47+3*np.cos(theta)] for theta in np.linspace(0, 2*np.pi, 25)] for lon in np.linspace(-150, 150, 13)], }, 'properties': { 'times': [1435708800000+i*86400000 for i in np.linspace(0, 25, 13)] } }, { 'type': 'Feature', 'geometry': { 'type': 'MultiPolygon', 'coordinates': coordinates, }, 'properties': { 'times': [1435708800000+i*86400000 for i in np.linspace(0, 25, 7)] } }, ], } m = folium.Map([47, 3], zoom_start=1) tgj = plugins.TimestampedGeoJson(data) m.add_child(tgj) m._repr_html_() out = m._parent.render() # Verify the imports. assert ('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/' 'jquery.min.js"></script>' ) in out assert ('<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/' '1.10.2/jquery-ui.min.js"></script>' ) in out assert ('<script src="https://rawgit.com/nezasa/' 'iso8601-js-period/master/iso8601.min.js"></script>' ) in out assert ('<script src="https://rawgit.com/socib/Leaflet.' 'TimeDimension/master/dist/leaflet.timedimension.min.js">' '</script>' ) in out assert ('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/' 'libs/highlight.js/8.4/styles/default.min.css" />' ) in out assert ('<link rel="stylesheet" href="http://apps.socib.es/Leaflet.' 'TimeDimension/dist/leaflet.timedimension.control.min.css" />' ) in out assert ('<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js">' '</script>' ) in out # Verify that the script is okay. tmpl = Template(""" L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({ _getDisplayDateFormat: function(date){ var newdate = new moment(date); console.log(newdate) return newdate.format("{{this.date_options}}"); } }); {{this._parent.get_name()}}.timeDimension = L.timeDimension({period:"{{this.period}}"}); var timeDimensionControl = new L.Control.TimeDimensionCustom({{ this.options }}); {{this._parent.get_name()}}.addControl(this.timeDimensionControl); function __propagateProperties(props) { if(!props) { return {}; } var propertiesToExtract = {{ this.propagate_properties }}, ps = {}; if(propertiesToExtract.length == 0) { return {}; } for(var i = 0, p = null;i < propertiesToExtract.length;i++) { var p = propertiesToExtract[i]; if(props[p]) { ps[p] = props[p]; } } return ps; } function __merge(first, second) { var merged = {}; first = first || {}; second = second || {}; for (var attrname in first) { merged[attrname] = first[attrname]; } for (var attrname in second) { merged[attrname] = second[attrname]; } return merged; } console.log("{{this.marker}}"); var geoJsonLayer = L.geoJson({{this.data}}, { pointToLayer: function (feature, latLng) { if (feature.properties.icon == 'marker') { if(feature.properties.iconstyle){ return new L.Marker(latLng, __merge(__propagateProperties(feature.properties), { icon: L.icon(feature.properties.iconstyle)})); } //else return new L.Marker(latLng, __propagateProperties(feature.properties)); } if (feature.properties.icon == 'circle') { if (feature.properties.iconstyle) { return new L.circleMarker(latLng, __merge(__propagateProperties(feature.properties), feature.properties.iconstyle)) } //else return new L.circleMarker(latLng, __propagateProperties(feature.properties)); } //else return new L.Marker(latLng, __propagateProperties(feature.properties)); }, style: function (feature) { return feature.properties.style; }, onEachFeature: function(feature, layer) { if (feature.properties.popup) { layer.bindPopup(feature.properties.popup); } } }) var {{this.get_name()}} = L.timeDimension.layer.geoJson(geoJsonLayer, {updateTimeDimension: true,addlastPoint: {{'true' if this.add_last_point else 'false'}}} ).addTo({{this._parent.get_name()}}); """) # noqa assert ''.join(tmpl.render(this=tgj).split()) in ''.join(out.split()) bounds = m.get_bounds() assert bounds == [[-53.0, -158.0], [50.0, 158.0]], bounds
"geometry": { "type": "Point", "coordinates": point['coordinates'], }, "properties": { "time": point['time'], "id": "plane", 'icon': 'marker', 'iconstyle': { 'iconUrl': point['icon_url'], 'iconSize': [20, 20] } } } for point in points] plugins.TimestampedGeoJson({ 'type': 'FeatureCollection', 'features': features }, period='PT10S', add_last_point=True, auto_play=False, loop=False, loop_button=True, max_speed=0.1, time_slider_drag_update=False, duration='PT0S').add_to(m) os.makedirs('output', exist_ok=True) m.save(args.input_files[2])
def test_propagates_named_feature_properties_when_asked(): data = { 'type': 'FeatureCollection', 'features': [ { 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [0, 0], }, 'properties': { 'times': [1435708800000 + 12 * 86400000] } }, ] } data['features'][0]['properties']['rotationAngle'] = 45 m = folium.Map([47, 3], zoom_start=1) tgj = plugins.TimestampedGeoJson(data, propagate_properties=['rotationAngle']) m.add_child(tgj) out = m._parent.render() # language=js tmpl = Template(""" L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({ _getDisplayDateFormat: function(date){ var newdate = new moment(date); console.log(newdate) return newdate.format("{{this.date_options}}"); } }); {{this._parent.get_name()}}.timeDimension = L.timeDimension({period:"{{this.period}}"}); var timeDimensionControl = new L.Control.TimeDimensionCustom({{ this.options }}); {{this._parent.get_name()}}.addControl(this.timeDimensionControl); function __propagateProperties(props) { if(!props) { return {}; } var propertiesToExtract = ["rotationAngle"], ps = {}; if(propertiesToExtract.length == 0) { return {}; } for(var i = 0, p = null;i < propertiesToExtract.length;i++) { var p = propertiesToExtract[i]; if(props[p]) { ps[p] = props[p]; } } return ps; } function __merge(first, second) { var merged = {}; first = first || {}; second = second || {}; for (var attrname in first) { merged[attrname] = first[attrname]; } for (var attrname in second) { merged[attrname] = second[attrname]; } return merged; } console.log("{{this.marker}}"); var geoJsonLayer = L.geoJson({{this.data}}, { pointToLayer: function (feature, latLng) { if (feature.properties.icon == 'marker') { if(feature.properties.iconstyle){ return new L.Marker(latLng, __merge(__propagateProperties(feature.properties), { icon: L.icon(feature.properties.iconstyle)})); } //else return new L.Marker(latLng, __propagateProperties(feature.properties)); } if (feature.properties.icon == 'circle') { if (feature.properties.iconstyle) { return new L.circleMarker(latLng, __merge(__propagateProperties(feature.properties), feature.properties.iconstyle)) } //else return new L.circleMarker(latLng, __propagateProperties(feature.properties)); } //else return new L.Marker(latLng, __propagateProperties(feature.properties)); }, style: function (feature) { return feature.properties.style; }, onEachFeature: function(feature, layer) { if (feature.properties.popup) { layer.bindPopup(feature.properties.popup); } } }) var {{this.get_name()}} = L.timeDimension.layer.geoJson(geoJsonLayer, {updateTimeDimension: true,addlastPoint: {{'true' if this.add_last_point else 'false'}}} ).addTo({{this._parent.get_name()}}); """) # noqa assert tmpl.render(this=tgj) in out
def test_timestamped_geo_json(): coordinates = [[[[lon - 8 * np.sin(theta), -47 + 6 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)], [[lon - 4 * np.sin(theta), -47 + 3 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)]] for lon in np.linspace(-150, 150, 7)] data = { 'type': 'FeatureCollection', 'features': [ { 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [0, 0], }, 'properties': { 'times': [1435708800000 + 12 * 86400000] } }, { 'type': 'Feature', 'geometry': { 'type': 'MultiPoint', 'coordinates': [[lon, -25] for lon in np.linspace(-150, 150, 49)], }, 'properties': { 'times': [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 49) ] } }, { 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': [[lon, 25] for lon in np.linspace(-150, 150, 25)], }, 'properties': { 'times': [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 25) ], 'style': { 'color': 'red' }, }, }, { 'type': 'Feature', 'geometry': { 'type': 'MultiLineString', 'coordinates': [[[lon - 4 * np.sin(theta), 47 + 3 * np.cos(theta)] for theta in np.linspace(0, 2 * np.pi, 25)] for lon in np.linspace(-150, 150, 13)], }, 'properties': { 'times': [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 13) ] } }, { 'type': 'Feature', 'geometry': { 'type': 'MultiPolygon', 'coordinates': coordinates, }, 'properties': { 'times': [ 1435708800000 + i * 86400000 for i in np.linspace(0, 25, 7) ] } }, ], } m = folium.Map([47, 3], zoom_start=1) tgj = plugins.TimestampedGeoJson(data).add_to(m) out = normalize(m._parent.render()) # Verify the imports. assert '<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>' in out assert '<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>' in out assert '<script src="https://cdn.jsdelivr.net/npm/[email protected]/iso8601.min.js"></script>' in out assert '<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.timedimension.min.js"></script>' in out # noqa assert '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/default.min.css"/>' in out # noqa assert '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.timedimension.control.css"/>' in out # noqa assert '<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>' in out # Verify that the script is okay. tmpl = Template(""" L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({ _getDisplayDateFormat: function(date){ var newdate = new moment(date); console.log(newdate) return newdate.format("{{this.date_options}}"); } }); {{this._parent.get_name()}}.timeDimension = L.timeDimension( { period: {{ this.period|tojson }}, } ); var timeDimensionControl = new L.Control.TimeDimensionCustom( {{ this.options|tojson }} ); {{this._parent.get_name()}}.addControl(this.timeDimensionControl); var geoJsonLayer = L.geoJson({{this.data}}, { pointToLayer: function (feature, latLng) { if (feature.properties.icon == 'marker') { if(feature.properties.iconstyle){ return new L.Marker(latLng, { icon: L.icon(feature.properties.iconstyle)}); } //else return new L.Marker(latLng); } if (feature.properties.icon == 'circle') { if (feature.properties.iconstyle) { return new L.circleMarker(latLng, feature.properties.iconstyle) }; //else return new L.circleMarker(latLng); } //else return new L.Marker(latLng); }, style: function (feature) { return feature.properties.style; }, onEachFeature: function(feature, layer) { if (feature.properties.popup) { layer.bindPopup(feature.properties.popup); } if (feature.properties.tooltip) { layer.bindTooltip(feature.properties.tooltip); } } }) var {{this.get_name()}} = L.timeDimension.layer.geoJson( geoJsonLayer, { updateTimeDimension: true, addlastPoint: {{ this.add_last_point|tojson }}, duration: {{ this.duration }}, } ).addTo({{this._parent.get_name()}}); """) # noqa expected = normalize(tmpl.render(this=tgj)) assert expected in out bounds = m.get_bounds() assert bounds == [[-53.0, -158.0], [50.0, 158.0]], bounds
def main(argv): db = Database() """ pi = [ {'$match': {'trip.routeId': '467'}}, {'$group': {'_id': '$trip.tripId', 'rr': {'$first': '$trip.routeId'}}} ] """ pi = [{'$match': {'$and': [{'vehicle.id': {'$in': ['HR55AF0643']}}]}}] l = list(db.aggregate('vehicle_position', pi)) print(len(l)) """ print(l[0]) print(l[len(l)-1]) """ j = GeoTrace() for i in l: j.add_point(timestamp=i['timestamp'], latitude=i['position']['latitude'], longitude=i['position']['longitude']) m = init_folium() geo = [] for k, v in j.items(): geo.append({ 'time': k.strftime('%Y/%m/%d %H:%M:%S'), 'coordinates': [v.longitude, v.latitude] }) """ marker = folium.Marker( location = [v.latitude, v.longitude], popup = str(k) ) m.add_child(marker) """ #print(geo) features = [{ 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': point['coordinates'], }, 'properties': { 'time': point['time'], 'popup': point['time'], 'id': 'house', 'icon': 'marker' } } for point in geo] plugins.TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': features }, period='PT1M', add_last_point=True, auto_play=False, loop=False, max_speed=1, loop_button=True, date_options='YYYY/MM/DD HH:mm:ss', time_slider_drag_update=True, duration='PT1M').add_to(m) m.save('index.html')