コード例 #1
0
def create_fault_layer():
    blind_faults = shapefile.Reader(faults_blind)
    nonblind_faults = shapefile.Reader(faults_nonblind)

    faults = [
        dl.Polyline(
            color='#404040',
            weight=1.25,
            dashArray='2, 3',
            positions=[[
                coord[1], coord[0]
            ] for coord in feature.shape.__geo_interface__['coordinates']])
        for feature in blind_faults.shapeRecords()
    ]

    faults += [
        dl.Polyline(
            color='black',
            weight=1,
            positions=[[
                coord[1], coord[0]
            ] for coord in feature.shape.__geo_interface__['coordinates']])
        for feature in nonblind_faults.shapeRecords()
    ]

    return dl.LayerGroup(id='fault-layer', children=faults)
コード例 #2
0
def make_empty_map(lat_center=51.326863, lon_center=10.354922, zoom=5):
    fig = [
        dl.Map(
            [
                dl.TileLayer(url=mapURL,
                             attribution=attribution,
                             tileSize=512,
                             zoomOffset=-1),
                dl.LayerGroup(id="layer"),
                dl.WMSTileLayer(url="https://maps.dwd.de/geoserver/ows?",
                                layers="dwd:RX-Produkt",
                                format="image/png",
                                transparent=True,
                                opacity=0.7,
                                version='1.3.0',
                                detectRetina=True),
                dl.LocateControl(
                    options={'locateOptions': {
                        'enableHighAccuracy': True
                    }}),
            ],
            center=[lat_center, lon_center],
            zoom=zoom,
            style={
                'width': '100%',
                'height': '45vh',
                'margin': "auto",
                "display": "block"
            },
            id='map')
    ]

    return fig
コード例 #3
0
def get_event_layer(eq_data, sizes, colors, opacities):
    """Return a LayerGroup that contains earthquakes represented as circles.

    Keyword arguments:
    eq_data -- EarthquakeData object containing the quakes to be drawn.
    sizes -- An array containing a size for each data point
    colors -- An array containing a color for each data point
    opacities -- An array containing an opacity for each data point
    """

    quake_circles = [
        dl.Circle(center=[quake['LATITUDE'], quake['LONGITUDE']],
                  radius=sizes[idx],
                  color=colors[idx],
                  fillOpacity=opacities[idx],
                  weight=2,
                  children=[
                      dl.Popup(dcc.Markdown(
                          list(
                              map(
                                  lambda x: '**{}**: {}  '.format(
                                      x.replace('[', r'\['), quake[x]),
                                  quake.keys()))),
                               className='earthquake-popup')
                  ]) for idx, quake in eq_data.data.reset_index().iterrows()
    ]

    return dl.LayerGroup(id='layer-id', children=quake_circles)
コード例 #4
0
ファイル: alerts.py プロジェクト: pyronear/pyro-platform
def build_alerts_map():
    """
    The following function mobilises functions defined hereabove or in the utils module to
    instantiate and return a dl.Map object, corresponding to the "Alerts and Infrastructure" view.
    """
    map_object = dl.Map(
        center=[44.73,
                4.27],  # Determines the point around which the map is centered
        zoom=9,  # Determines the initial level of zoom around the center point
        children=[
            dl.TileLayer(id='tile_layer'),
            build_departments_geojson(),
            build_filters_object(map_type='alerts'),
            build_legend_box(map_type='alerts'),
            dl.MarkerClusterGroup(
                children=build_sites_markers(sites_with_live_alerts=[]),
                id='sites_markers'),
            dl.LayerGroup(id='vision_polygons'),
            html.Div(id="live_alerts_marker"),
            html.Div(id="live_alert_header_btn"),
            html.Div(id='fire_markers_alerts')
        ],  # Will contain the past fire markers of the alerts map
        style=map_style,  # Reminder: map_style is imported from utils.py
        id='map')

    return map_object
コード例 #5
0
 def create_map(self):
     self.ns = Namespace("dlx", "scatter")
     self.markers = [
         dl.Marker(
             dl.Tooltip(f"({pos[0]}, {pos[1]}), time:{self.times[i]}"),
             position=pos,
             id="marker{}".format(i))
         for i, pos in enumerate(self.locations)
     ]
     self.cluster = dl.MarkerClusterGroup(
         id="markers",
         children=self.markers,
         options={"polygonOptions": {
             "color": "red"
         }})
     self.app = dash.Dash(external_scripts=[
         "https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js"
     ])
     self.polyline = dl.Polyline(positions=self.locations)
     self.app.layout = html.Div([
         dl.Map([
             dl.TileLayer(), self.cluster, self.polyline,
             dl.LayerGroup(id="layer")
         ],
                id="map",
                center=(40.4259, -86.9081),
                zoom=8,
                style={'height': '100vh'}),
     ])
コード例 #6
0
def get_location_uncertainty_layer(eq_data, visible):
    """Return a map layer with uncertainties visualized for each data point.

    Keyword arguments:
    eq_data -- An Earthquake data object containing the data visible on the map
    visible -- A boolean indicating whether to display the uncertainties in
        location of each data point
    """
    if eq_data.data.shape[0] == 0 or not visible:
        return dl.LayerGroup(id='location-uncertainties')

    location_uncertainties = eq_data.get_location_uncertainties()
    reset_data = eq_data.data.reset_index()
    uncertainties = []

    if type(location_uncertainties) == int:
        uncertainties = [
            dl.Circle(center=[quake['LATITUDE'], quake['LONGITUDE']],
                      radius=location_uncertainties,
                      color='black',
                      fillOpacity=0,
                      dashArray='5, 5',
                      weight=1.5,
                      children=[
                          dl.Popup(dcc.Markdown(
                              list(
                                  map(
                                      lambda x: '**{}**: {}  '.format(
                                          x.replace('[', r'\['), quake[x]),
                                      quake.keys()))),
                                   className='earthquake-popup')
                      ]) for _, quake in reset_data.iterrows()
        ]

    else:
        uncertainties += [
            dl.Polyline(positions=[[
                quake['LATITUDE'], quake['LONGITUDE']
            ], location_uncertainties[idx + direction * reset_data.shape[0]]],
                        color='black',
                        dashArray='5, 5',
                        weight=1.5) for direction in range(4)
            for idx, quake in reset_data.iterrows()
        ]

    return dl.LayerGroup(id='location-uncertainties', children=uncertainties)
コード例 #7
0
ファイル: utils.py プロジェクト: pyronear/pyro-platform
def build_historic_markers(dpt_code=None):
    """
    This function reads through the 'historic_fires.csv' file stored in the /data folder.

    It takes as input a department code (as a character string), which will correspond to the department
    on which the user chooses to click and it returns past fires (as markers on the map) for this area.

    More precisely, it returns a dl.LayerGroup object that gathers all relevant past fire markers.
    """

    # As long as the user does not click on a department, dpt_code is None and we return no fire marker
    if not dpt_code:
        return None

    # We read the csv file that locates the old fires
    old_fire_positions = pd.read_csv(Path(__file__).parent.joinpath('data', 'historic_fires.csv'), ',')

    # The line below allows us to filter for the department of interest
    old_fire_positions = old_fire_positions[old_fire_positions['Département'] == int(dpt_code)].copy()

    icon = {"iconUrl": '../assets/pyro_oldfire_icon.png',
            "iconSize": [50, 50],       # Size of the icon
            "iconAnchor": [25, 45],      # Point of the icon which will correspond to marker's and popup's location
            "popupAnchor": [0, -20]  # Point from which the popup should open relative to the iconAnchor
            }

    # We build a list of dictionaries containing the coordinates of each fire
    fire_markers = []
    for i, row in old_fire_positions.iterrows():
        lat = row['latitude']
        lon = row['longitude']
        location = row['location']
        date = datetime.datetime.strptime(row['acq_date'], '%Y-%m-%d')\
                                .strftime('%d %b %Y')

        if row['daynight'] == 'D':
            daynight = 'Diurne'
        elif row['daynight'] == 'N':
            daynight = 'Nocturne'
        else:
            daynight = None

        fire_markers.append(dl.Marker(id=f'historic_fire_{i}',  # Set an id for each marker to receive callbacks
                                      position=(lat, lon),
                                      icon=icon,
                                      children=[dl.Tooltip(f"Date: {date}"),
                                                dl.Popup([html.H4(f'Incendie du {date}'),
                                                          html.P(f'Commune : {location}'),
                                                          html.P(f'Type : {daynight}')])
                                                ]
                                      )
                            )

    # We gather all markers stored in the fire_markers list in a dl.LayerGroup object, which is returned
    return dl.LayerGroup(children=fire_markers,
                         id='historic_fires_markers')
コード例 #8
0
def get_fault_layer(show_faults=False):
    """Return a LayerGroup that contains the Southern California
    fault lines as PolyLines.

    Blind faults are represented by dashed, dark grey lines and
    non-blind faults by solid, black lines.

    Keyword arguments:
    show_faults -- A boolean indicating whether to show the faults
    """
    if show_faults:
        return fault_layer
    return dl.LayerGroup(id='fault-layer', children=[])
コード例 #9
0
def plot_coordinate(value='11 Cadogan Gardens'):
    search_data = df[df['Hotel_Name'] == value]

    lat = search_data.lat.values[0]
    lng = search_data.lng.values[0]
    name = search_data.Hotel_Name.values[0]
    address_ = search_data.Hotel_Address.values[0]

    markers = [
        dl.Marker(
            position=[lat, lng],
            children=[dl.Popup('Name: ' + name + ', Address: ' + address_, )])
    ]

    return html.Div([
        dl.Map([dl.TileLayer(), dl.LayerGroup(id="layer")] +
               [dl.LayerGroup(markers)],
               center=[lat, lng],
               zoom=14,
               id="map",
               style=MAP_STYLE),
    ]),
コード例 #10
0
def update_routes(agregation_option, routes):
    # Routes Layer Map
    df = df_routes.copy()
    df = df[df[agregation_option].isin(routes)]
    map_routes_children = []
    for row in df.itertuples():
        map_routes_children.append(dl.Polygon(positions = [(p[1], p[0]) for p in row.geometry.exterior.coords],
                                              children = dl.Tooltip(row.Route),
                                              color = dict_colors[row.Route],
                                              fillColor = dict_colors[row.Route]
                                              )
                                   )
    
    return dl.LayerGroup(map_routes_children),
コード例 #11
0
def generate_map_plot(data):
    if data is not None:
        start_point = data['STATION_NAME'].item()
        point = [data['LAT'].item(), data['LON'].item()]

        fig = [
            dl.Map(
                [
                    dl.TileLayer(url=mapURL,
                                 attribution=attribution,
                                 tileSize=512,
                                 zoomOffset=-1),
                    dl.LayerGroup(id="layer"),
                    dl.WMSTileLayer(url="https://maps.dwd.de/geoserver/ows?",
                                    layers="dwd:SAT_WELT_KOMPOSIT",
                                    format="image/png",
                                    transparent=True,
                                    opacity=0.7,
                                    version='1.3.0',
                                    detectRetina=True),
                    dl.WMSTileLayer(url="https://maps.dwd.de/geoserver/ows?",
                                    layers="dwd:SAT_EU_RGB",
                                    format="image/png",
                                    transparent=True,
                                    opacity=0.7,
                                    version='1.3.0',
                                    detectRetina=True),
                    dl.LocateControl(options={
                        'locateOptions': {
                            'enableHighAccuracy': True
                        }
                    }),
                    dl.Marker(position=point,
                              children=dl.Tooltip(start_point)),
                ],
                center=point,
                zoom=4,
                style={
                    'width': '100%',
                    'height': '35vh',
                    'margin': "auto",
                    "display": "block"
                },
                id='map')
        ]
    else:  # make an empty map
        fig = make_empty_map()

    return fig
コード例 #12
0
ファイル: quake_map.py プロジェクト: afhuertass/QuakeWatch
def get_event_layer(eq_data):
    """Return a LayerGroup that contains earthquakes represented as circles.

    Keyword arguments:
    eq_data -- EarthquakeData object containing the quakes to be drawn.
    """

    quake_circles = [
        dl.Circle(center=[quake['LATITUDE'], quake['LONGITUDE']],
                  radius=100,
                  color='red',
                  fillOpacity=0.1,
                  weight=2) for _, quake in eq_data.data.iterrows()
    ]

    return dl.LayerGroup(id='layer-id', children=quake_circles)
コード例 #13
0
def update_events(start_date, end_date, agregation_option,routes):
    # Events Layer Map
    df = df_events.copy()
    df = df[(df[agregation_option].isin(routes)) & (df['Reported Date'].between(start_date, end_date))]
    df['color'] = [select_df_color[agregation_option][r] for r in df[agregation_option]]
    map_events_children = []

    for row in df.itertuples():
        map_events_children.append(dl.Marker(position = [row.geometry.y, row.geometry.x],
                                             children = dl.Popup('Reported Date: {}'.format(row._1.date()
                                                                                            )
                                                                 )
                                             )
                                   )

    return dl.LayerGroup(map_events_children),
コード例 #14
0
def generate_map_plot(df):
    if df is not None:
        lons = df.lons.values
        lats = df.lats.values
        trajectory = np.vstack([lats, lons]).T.tolist()
        start_point = df.source.values[0]
        end_point = df.destination.values[0]
        zoom, center = zoom_center(lons, lats, width_to_height=8)

        fig = [
            dl.Map(
                [
                    dl.TileLayer(url=mapURL,
                                 attribution=attribution,
                                 tileSize=512,
                                 zoomOffset=-1),
                    dl.LayerGroup(id="layer"),
                    dl.WMSTileLayer(url="https://maps.dwd.de/geoserver/ows?",
                                    layers="dwd:RX-Produkt",
                                    format="image/png",
                                    transparent=True,
                                    opacity=0.7),
                    dl.LocateControl(options={
                        'locateOptions': {
                            'enableHighAccuracy': True
                        }
                    }),
                    dl.Polyline(positions=trajectory),
                    dl.Marker(position=trajectory[0],
                              children=dl.Tooltip(start_point)),
                    dl.Marker(position=trajectory[-1],
                              children=dl.Tooltip(end_point))
                ],
                center=[center['lat'], center['lon']],
                zoom=zoom,
                style={
                    'width': '100%',
                    'height': '45vh',
                    'margin': "auto",
                    "display": "block"
                },
                id='map')
        ]
    else:  # make an empty map
        fig = make_empty_map()

    return fig
コード例 #15
0
 html.Div(id='print_districts',
          style={
              'font-size': '14px',
              'display': 'inline-block'
          }),
 html.Hr(),
 html.Div([
     html.Div(
         # Fifth: row contains map and graph
         dl.Map(
             id="map",
             # Order of this list determines overlay order
             children=[
                 grid_rivers,
                 dl.TileLayer(),
                 dl.LayerGroup(id="start_marker"),
                 dl.LayerGroup(id='rec_neighbours'),
                 dl.LayerGroup(id='rec_pois'),
                 dl.LayerGroup(id='marker_stations'),
                 dl.LayerGroup(id="marker_floods"), color_bar, grid_geo,
                 districts_geo
             ],
             zoom=7,
             center=[1.40, 32.30],
             doubleClickZoom=True,
             maxBounds=bounds_uganda),
         style={
             'width': '60%',
             'height': '70vh',
             "display": "inline-block"
         }),
コード例 #16
0
def get_app():
    """Create a new Dash instance with a Terracotta instance embedded in it.

    Args:
        tc_app: Flask instance of Terracotta

    Returns:
        A Flask instance of a Dash app.
    """
    # pylint: disable=unused-variable
    data = _get_data()
    app = dash.Dash(__name__, server=False)
    app.title = 'Taswira'
    options = [{'label': k, 'value': k} for k in list(data)]
    app.layout = html.Div(
        [
            dcc.Store(id='raster-layers-store'),
            dcc.Dropdown(id='title-dropdown',
                         clearable=False,
                         options=options,
                         value=options[0]['value'],
                         style={
                             'position': 'relative',
                             'top': '5px',
                             'zIndex': '500',
                             'height': '0',
                             'maxWidth': '200px',
                             'marginLeft': 'auto',
                             'marginRight': '10px'
                         }),
            html.Div(dl.Map([
                dl.TileLayer(attribution=BASE_MAP_ATTRIBUTION),
                dl.LayerGroup(id='raster-layers'),
                dl.LayerGroup(id='colorbar-layer')
            ],
                            id='main-map'),
                     id='main-map-div',
                     style={
                         'position': 'relative',
                         'width': '100%',
                         'height': '70%',
                         'top': '0',
                         'left': '0'
                     }),
            html.Div(
                [
                    html.Button(id='animation-btn'),
                    dcc.Interval(id='animation-interval', disabled=True)
                ],
                style={
                    'position': 'relative',
                    'top': '-50px',
                    'left': '10px',
                    'zIndex': '500',
                    'height': '0',
                },
                id="animation-control"),
            html.Div(
                [dcc.Slider(
                    id='year-slider',
                    step=None,
                    value=0,
                )],
                style={
                    'position': 'relative',
                    'top': '-50px',
                    'left': '60px',
                    'zIndex': '500',
                    'height': '0',
                    'marginRight': '9em'
                },
                id='year-slider-div'),
            dcc.Graph(id='indicator-change-graph',
                      responsive=True,
                      style={
                          'width': '100%',
                          'height': '30%'
                      })
        ],
        style={
            'position': 'absolute',
            'width': '100%',
            'height': '100%',
            'top': '0',
            'left': '0',
            'fontFamily': 'sans-serif'
        })

    app.clientside_callback(
        """
        function(year, layers){
            return layers.map(l => {
                console.log(typeof l.props.id, typeof year);
                if (Number(l.props.id) === year)
                    return {...l,props: {...l.props, opacity: 1.0}};
                return l;
            });
        }
        """, Output('raster-layers', 'children'),
        [Input('year-slider', 'value'),
         Input('raster-layers-store', 'data')],
        [State('raster-layers', 'children')])

    @app.callback([
        Output('raster-layers-store', 'data'),
        Output('colorbar-layer', 'children'),
        Output('main-map', 'bounds')
    ], [Input('title-dropdown', 'value')])
    def update_raster_layers_colobar_map_bounds(title):
        ranges = [data[title][year]['range'] for year in data[title].keys()]
        lowers, uppers = list(zip(*ranges))
        stretch_range = [min(lowers), max(uppers)]

        xyz = '{z}/{x}/{y}'
        layers = []
        for year in data[title]:
            raster_data = data[title][year]
            colormap = raster_data['metadata']['colormap']
            bounds = format_bounds(raster_data['bounds'])
            layers.append(
                dl.TileLayer(
                    url=
                    f'/singleband/{title}/{year}/{xyz}.png?colormap={colormap}',
                    opacity=0,
                    id=year))

        colorbar = get_colorbar(stretch_range, colormap)

        return layers, [colorbar], bounds

    @app.callback([
        Output('year-slider', 'marks'),
        Output('year-slider', 'min'),
        Output('year-slider', 'max'),
    ], [Input('title-dropdown', 'value')])
    def update_slider(title):
        mark_style = {'color': '#fff', 'textShadow': '1px 1px 2px #000'}
        marks = {
            int(k): dict(label=k, style=mark_style)
            for k in data[title].keys()
        }
        min_value = min(marks.keys())
        max_value = max(marks.keys())

        return marks, min_value, max_value

    @app.callback(Output('year-slider', 'value'), [
        Input('year-slider', 'marks'),
        Input('animation-interval', 'n_intervals')
    ], [State('year-slider', 'value')])
    def update_slider_value(marks, n_intervals, current_value):  # pylint: disable=unused-argument
        ctx = dash.callback_context
        min_value = min(marks.keys())

        if ctx.triggered:
            trigger = ctx.triggered[0]['prop_id'].split('.')[0]
            trigger_value = ctx.triggered[0]['value']
            if trigger == 'animation-interval' and trigger_value:
                new_value = get_element_after(str(current_value),
                                              iter(marks.keys()))
                if new_value is not None:
                    return int(new_value)
            elif current_value:
                return current_value

        return int(min_value)

    @app.callback(Output('indicator-change-graph', 'figure'),
                  [Input('title-dropdown', 'value')])
    def update_graph(title):
        fig = go.Figure()
        x_marks = []
        y_margs = []
        for year, meta in data[title].items():
            x_marks.append(year)
            y_margs.append(meta['metadata']['indicator_value'])
        fig.add_trace(go.Scatter(x=x_marks, y=y_margs, mode='lines+markers'))

        unit = ''
        for _, meta in data[title].items():
            unit = meta['metadata']['unit']
            break

        fig.update_layout(autosize=False,
                          xaxis_title='Year',
                          yaxis_title=f'{title} ({unit})',
                          xaxis_type='category',
                          height=150,
                          margin=dict(t=10, b=0))
        return fig

    @app.callback(Output('animation-control', 'children'),
                  [Input('animation-btn', 'n_clicks')], [
                      State('animation-btn', 'value'),
                  ])
    def update_animation_control(n_clicks, current_value):  # pylint: disable=unused-argument
        new_value = 'pause' if current_value == 'play' else 'play'
        btn = html.Button(new_value.capitalize(),
                          value=new_value,
                          id='animation-btn',
                          style={
                              'height': '30px',
                              'backgroundColor': '#fff',
                              'textAlign': 'center',
                              'borderRadius': '4px',
                              'border': '2px solid rgba(0,0,0,0.2)',
                              'fontWeight': 'bold'
                          })
        is_paused = (new_value == 'play')
        interval = dcc.Interval(id='animation-interval', disabled=is_paused)
        return [btn, interval]

    return app
コード例 #17
0
ファイル: app.py プロジェクト: even311379/DashLandArea
import style
from setting import app
from elements import country_dropdown

server = app.server

app.layout = dbc.Container([
    dcc.Location(id='url', refresh=False),
    dbc.Row('土地面積計算', className="h1 text-primary py-5", justify='center'),
    dbc.Row([
        dbc.Col(dl.Map([
            dl.TileLayer(
                url='http://mt0.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}',
                maxZoom=20),
            dl.LayerGroup(id="drawing"),
            dl.LayerGroup([], id="polygons")
        ],
                       id="map",
                       style=style.map,
                       center=(23.5, 120.5),
                       zoom=8),
                width=6,
                className='pl-5'),
        dbc.Col([dbc.Row('', id='client_ip'),
                 dbc.Row(country_dropdown)],
                width=6,
                className='pr-5')
    ]),
    dcc.Store(id="store", data=[])
],
コード例 #18
0
ファイル: app - old.py プロジェクト: rheinheimer/sierra-dash
def render_map(show_labels):
    show_labels = 'show-all-labels' in show_labels
    simplify = False
    nodes = []
    links = []
    lats = []
    lons = []
    tt_paths = {}
    for i, (abbr, full_name) in enumerate(BASINS.items()):
        oa_network_path = '../openagua_schematics/{} River.json'.format(
            full_name)
        if not os.path.exists(oa_network_path):
            continue
        with open(oa_network_path) as f:
            oa_network = json.load(f)
        pywr_model_path = '../{}/temp/pywr_model_Livneh_simplified.json'.format(
            full_name.replace(' ', '_').lower())
        if not os.path.exists(pywr_model_path):
            continue
        with open(pywr_model_path) as f:
            pywr_network = json.load(f)

        net = oa_network['network']
        tmpl = oa_network['template']
        node_lookup = {n['name']: n for n in net['nodes']}

        if i == 0:
            for tt in tmpl['templatetypes']:
                tt_name = tt['name']
                tt_svg = tt['layout'].get('svg')
                if not tt_svg:
                    continue
                tt_path = './icons/{}.svg'.format(tt_name.replace(' ', '_'))
                with open(os.path.join('./assets', tt_path), 'w') as f:
                    f.write(tt_svg)
                tt_paths[tt['name']] = tt_path

        if simplify:
            for n in pywr_network['nodes']:
                if n['name'] not in node_lookup:
                    continue
                node = node_lookup[n['name']]
                lat, lon = float(node['y']), float(node['x'])
                lats.append(lat)
                lons.append(lon)
                nodes.append(leaflet.Marker(position=[lat, lon]))

            for n1, n2 in pywr_network['edges']:
                if n1 not in node_lookup or n2 not in node_lookup:
                    continue
                node1 = node_lookup[n1]
                node2 = node_lookup[n2]
                lat1, lon1 = float(node1['y']), float(node1['x'])
                lat2, lon2 = float(node2['y']), float(node2['x'])
                positions = [[lat1, lon1], [lat2, lon2]]
                links.append(leaflet.Polyline(positions=positions))
        else:
            for node in net['nodes']:
                lat, lon = float(node['y']), float(node['x'])
                tt = [
                    t for t in node['types'] if t['template_id'] == tmpl['id']
                ][-1]

                tt_path = tt_paths.get(tt['name'])
                kwargs = {}
                if tt_path:
                    if tt['name'].lower(
                    ) == 'junction' or 'gauge' in tt['name'].lower():
                        size = 12
                    else:
                        size = 24
                    kwargs.update(icon=dict(iconUrl=app.get_asset_url(tt_path),
                                            iconSize=[size, size],
                                            iconAnchor=[size / 2, size / 2]))
                nodes.append(leaflet.Marker(position=[lat, lon], **kwargs))
                lats.append(lat)
                lons.append(lon)
            for link in net['links']:
                coords = link['layout']['geojson']['geometry']['coordinates']
                lons_, lats_ = zip(*coords)
                positions = list(zip(*[lats_, lons_]))
                tt = [
                    t for t in link['types'] if t['template_id'] == tmpl['id']
                ][-1]
                linestyle = tt['layout'].get('linestyle')
                if type(linestyle) == str:
                    try:
                        linestyle = json.loads(linestyle)
                    except:
                        linestyle = {}
                links.append(leaflet.Polyline(positions=positions,
                                              **linestyle))

    clat = (min(lats) + max(lats)) / 2
    clon = (min(lons) + max(lons)) / 2

    return [
        leaflet.Map(
            style={
                'width': '100%',
                'height': '100%'
            },
            center=[clat, clon],
            zoom=9,
            children=[
                leaflet.TileLayer(
                    url="https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"),
                leaflet.LayerGroup(children=nodes + links)
            ])
    ]
コード例 #19
0
ファイル: app.py プロジェクト: renodubois/data
        )
wards = dl.GeoJSON(
    data=ward_geojson,  # TODO: Faster is to get PBFs
    options={"style": {
        "color": "red",
        "fillOpacity": 0.5,
        "weight": 2
    }},
    zoomToBoundsOnClick=
    True,  # when true, zooms to bounds of feature (e.g. polygon) on click
    hoverStyle=arrow_function(
        dict(weight=4, fillOpacity=0.2,
             dashArray="")),  # special style applied on hover)
    id="wards-geojson",
)
ward_overlay = dl.Overlay(dl.LayerGroup(wards), name="wards", checked=True)


# 	Wards: Show election info on click
@app.callback(
    Output("ward-info-panel", "children"),
    [Input("wards-geojson", "click_feature")],
    State("election-dropdown", "value"),
)
def ward_click(feature, election_selected):
    div_children = []
    races_per_election = dict(
        aug_2020=dict(
            rep1_dem=dict(
                name="U.S Congress MO-1 (Democratic Primary)",
                candidates=["Clay", "Bush"],
コード例 #20
0
ファイル: app.py プロジェクト: cemac/BiB_extract
def tabulate(activetabs,hashkey):
    global df,params
    #
    # print
    # (activetabs,hashkey)

    if activetabs == 'filter':
        info('enabling filter options')
        params['precompute']= True
        return None,None,None


    if type(df) != type(None):

        # '''
        # table
        # '''

        if activetabs == 'table_tab':

            message = md('''
            # Table Sample
            Showing a *random* sample of *500* values from the selected dataframe
            ''')


            newdf = df
            if len(df)>500: newdf = newdf.sample(500).reset_index()

            try: newdf.drop(['UNIXTIME'],inplace=True)
            except: None

            print(newdf)
            return [message,br,table(newdf,'tab_table',{'width':'80%','margin':'auto'})],None,None


        # '''
        # scatter_tab
        # '''
        elif activetabs == 'scatter_tab':

            gc = 'PM1 PM3 PM2.5 PM10 UNIXTIME'.split()
            cols = list(filter(lambda x:x in gc ,df.columns))

            dfp = df[cols]
            dfp['hour'] = df.index.hour + (df.index.minute/15)//4


            dfp = dfp.groupby('hour').mean().reset_index()


            print(dfp)

            sizes = {'PM1':2,'PM2.5':3, 'PM3':3, 'PM10':10}
            alpha = 0.8


            for i in 'PM1 PM3 PM2.5 PM10'.split()[::-1]:
                if i in dfp.columns:
                    # print(i)
                    try:
                        ax = dfp.plot(kind='scatter',x='hour', y=i, c='UNIXTIME',colormap='viridis',ax=ax,colorbar=False,label=i, s = sizes[i],alpha = alpha)
                    except:
                        ax = dfp.plot(kind='scatter',x='hour', y=i, c='UNIXTIME',colormap='viridis', label=i, s = sizes[i],alpha=alpha)


            plt.legend()
            plt.tight_layout()
            plt.xlabel('HOUR')
            plt.ylabel('Avg value')

            '''
            save to a base 64str
            '''
            import base64
            import io
            IObytes = io.BytesIO()
            plt.savefig(IObytes,  format='png')
            plt.close()
            IObytes = base64.b64encode(IObytes.getvalue()).decode("utf-8").replace("\n", "")
            plot = html.Img(src="data:image/png;base64,{}".format(IObytes))


            return None,[md('# A grouped summary of the following dataframe:'),br,br,table(dfp.describe().reset_index(),'descplot'), br,br,plot],None


        elif activetabs == 'map_tab':

            dfp = df['LAT LON'.split()].dropna(subset=['LON'])
            if len(dfp)>1000: dfp.dfp.sample(1000)

            print(dfp)


            desc = md('''
            # Location overview
            An interactive map showing a *random* subset of *1000* datapoints from the selected subset.
            These vary between each initiation due to the above reason.

            The centre of the map is calculated by taking the median latitude and Longitude, the colour shows the time of day, and the tooltip produces the index value from the dataset.
            ''')


            log.critical('Known: -ves on Longitude are lost!!!!!')


            mid = (dfp.LAT.median(), -dfp.LON.median())

            dfp.columns = ['lat','lon']

            print(mid)

            cc = [dl.CircleMarker( dl.Tooltip(str(row[0])), center=(row[1].lat,-row[1].lon), radius=5, stroke=True,color='none',weight=0,fillColor='blue' ) for row in dfp.iterrows()]
            circles = dl.LayerGroup(cc,id='markers')


            ''' when the regeneratorRuntime issue is solved '''
            log.critical(' Known: cannot show superCluster due to regeneratorRuntime issue')
            # ll = dlx.dicts_to_geojson(dfp.to_dict('records'))
            #
            # # markers = dl.GeoJSON(data=ll, cluster=True, zoomToBoundsOnClick=True,
            # #        # superClusterOptions={"radius": 100}
            # #        )
            # markers = []




            plot =  html.Div(
                id="bibmap",
                children=[ desc,br,br,



                dl.Map([dl.TileLayer(),circles], center=mid, zoom=12,style={'width': '90vw', 'height': '50vh'})


            ],

            # style={'width': '100vw', 'height': '50vh', 'margin': "auto", "display": "block"}
            )


            return None,None,plot






        else:
            return None,None,None

    else:
        return None,None,None
コード例 #21
0
        "name": "viewport",
        "content": "width=device-width, initial-scale=1"
    }],
)
server = app.server

url = 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png'
attribution = '&copy; <a href="https://stadiamaps.com/">Stadia Maps</a> '
click_positions = []
if len(click_positions) > 2:
    click_positions = []

app.layout = html.Div([
    dl.Map([
        dl.TileLayer(url=url, maxZoom=20, attribution=attribution),
        dl.LayerGroup(id="position")
    ],
           id="map",
           style={
               'width': '100%',
               'height': '50vh',
               'margin': "auto",
               "display": "block"
           })
])


@app.callback(Output("position", "children"), [Input("map", "click_lat_lng")])
def map_click(dbl_click_lat_lng):
    click_positions.append(dbl_click_lat_lng)
    print(click_positions[-2:])
コード例 #22
0
def run():
    # defining the number of steps
    n = 500

    #creating two array for containing x and y coordinate
    #of size equals to the number of size and filled up with 0's
    x = numpy.zeros(n)
    y = numpy.zeros(n)
    global locations

    locations = []  #used in map generator
    locations_base = []  #the base data.
    start_location = [40.4259, -86.9081]
    at_risk = numpy.random.uniform(low=0.0, high=1.1, size=(n, ))
    start_time = 0
    map_dir = "index.html"
    MINUTES_IN_DAY = 1440
    start_date = datetime.datetime.now()

    times = list(range(0, n))
    time_index = 0
    datetimes = []

    for i in range(len(times)):
        noise = random.randint(1, 5)
        times[i] = (times[i] + noise)
        datetimes.append(start_date + timedelta(minutes=times[i]))

    datetimeindex = pd.Series(range(0, n), index=datetimes)

    #filling the coordinates with random variables
    for i in range(1, n):
        val = random.randint(1, 4)
        if val == 1:
            x[i] = x[i - 1] + 0.001
            y[i] = y[i - 1]
        elif val == 2:
            x[i] = x[i - 1] - 0.001
            y[i] = y[i - 1]
        elif val == 3:
            x[i] = x[i - 1]
            y[i] = y[i - 1] + 0.001
        else:
            x[i] = x[i - 1]
            y[i] = y[i - 1] - 0.001
        locations_base.append(
            [x[i] + start_location[0], y[i] + start_location[1]])

    ns = Namespace("dlx", "scatter")

    new_markers = [
        dl.Marker(dl.Tooltip(f"({pos[0]}, {pos[1]}), time:{times[i]}"),
                  position=pos,
                  id="marker{}".format(i)) for i, pos in enumerate(locations)
    ]

    cluster = dl.MarkerClusterGroup(
        id="new_markers",
        children=new_markers,
        options={"polygonOptions": {
            "color": "red"
        }})

    patterns = [dict(offset='0%', repeat='0', marker={})]
    polyline = dl.Polyline(positions=[locations], id="id_polyline")
    marker_pattern = dl.PolylineDecorator(id="id_marker_pattern",
                                          children=polyline,
                                          patterns=patterns)

    app = dash.Dash(external_scripts=[
        "https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js"
    ])
    app.layout = html.Div(
        html.Div([
            dl.Map([
                dl.TileLayer(), cluster, marker_pattern,
                dl.LayerGroup(id="layer")
            ],
                   id="map",
                   center=(40.4259, -86.9081),
                   zoom=8,
                   style={'height': '100vh'}),
            #html.Div(id='live-update-text'),
            dcc.Interval(
                id="interval",
                interval=1 * 1000,  # in milliseconds
                n_intervals=0)
        ]))

    @app.callback(Output('id_marker_pattern', 'children'),
                  [Input('interval', 'n_intervals')])
    def update_polyline(b):
        polyline = dl.Polyline(positions=locations)
        return polyline

    @app.callback(Output('new_markers', 'children'),
                  [Input('interval', 'n_intervals')])
    def update_metrics(a):

        locations.append([locations_base[a][0], locations_base[a][1]])
        if (len(locations) >= 100):
            locations.pop(0)
        new_markers = [
            dl.Marker(dl.Tooltip(f"({pos[0]}, {pos[1]}), time:{times[i]}"),
                      position=pos,
                      id="marker{}".format(i))
            for i, pos in enumerate(locations)
        ]
        return new_markers

    def rgb_to_hex(rgb):
        return ('%02x%02x%02x' % rgb)

    def get_time_interval(sd, ed):
        indices = datetimeindex[sd:ed].to_numpy()
        print(indices)

    def change_color_to_time():
        for i in range(len(locations)):
            time = times[i]
            r = 255 - math.trunc(255 * (time / MINUTES_IN_DAY))
            color_tuple = (r, r, r)
            rgb = rgb_to_hex(color_tuple)
            icon = {
                "iconUrl":
                f"http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|{rgb}&chf=a,s,ee00FFFF",
                "iconSize": [20, 30],  # size of the icon
            }
            markers[i].icon = icon

    def change_color_to_risk():
        for i in range(len(locations)):
            time = times[i]
            risk = math.trunc(at_risk[i])
            if (risk == 1):
                icon = {
                    "iconUrl":
                    "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|FF0000&chf=a,s,ee00FFFF",
                    "iconSize": [20, 30],  # size of the icon
                }
            else:
                icon = {
                    "iconUrl":
                    "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|00FF00&chf=a,s,ee00FFFF",
                    "iconSize": [20, 30],  # size of the icon
                }
            markers[i].icon = icon
            print("risk")

    def clamp(n, minn, maxn):
        return max(min(maxn, n), minn)

    def change_color_to_speed():
        speed = 0
        avewalk = 0.084
        speeddiff = 0

        for i in range(len(locations)):
            if i == 0:
                speed = 0
            elif (times[i] - times[i - 1]) == 0:
                speed = 0
            else:
                #coords_1 = [locations[i][0], locations[i][1]]
                #coords_2 = [locations[i-1][0], locations[i-1][1]]
                #distance = h3.point_dist(coords_1,coords_2)
                R = 6373.0
                lat1 = radians(locations[i][0])
                lon1 = radians(locations[i][1])
                lat2 = radians(locations[i - 1][0])
                lon2 = radians(locations[i - 1][1])
                dlon = lon2 - lon1
                dlat = lat2 - lat1
                a = 2
                ##sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
                c = 2
                ##2 * atan2(sqrt(a), sqrt(1 - a))
                distance = R * c
                speed = abs(distance / (times[i] - times[i - 1]))

            speeddiff = speed * 1000 / 60 - 1.4
            r = clamp(100 + speeddiff * 300, 0,
                      255)  #grey normal, yellow fast, blue slow
            g = clamp(100 + speeddiff * 100, 0, 255)
            b = clamp(100 - speeddiff * 100, 0, 255)
            color_tuple = (int(r), int(g), int(b))
            rgb = rgb_to_hex(color_tuple)
            icon = {
                "iconUrl":
                f"http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|{rgb}&chf=a,s,ee00FFFF",
                "iconSize": [20, 30],  # size of the icon
            }
            markers[i].icon = icon

    app.run_server(port=8050)
コード例 #23
0
url = 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png'
attribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'

map_coord = html.Div([
    html.P("Click on map to choose Coordinate:"),
    dl.Map(id="map-id",
           style={
               'width': '100%',
               'height': '300px'
           },
           center=NYC_coor,
           zoom=10,
           children=[
               dl.TileLayer(url=url, maxZoom=20, attribution=attribution),
               dl.LayerGroup(id="layer")
           ])
])

text1 = """On this page you can find a suggested price for your own Airbnb listing by moving the sliders to match your condo and clicking on the map to indicate the location.

We recommend choosing the position of your condo first, by navigating the map and zooming to its location and clicking. This way you can see the increase or decrease in price as you adjust how much of your condo you want to rent out, for how long, and if you need to buy a botnet to leave reviews on your listing to inflate the price.
"""

text2 = """Behind the scenes our machine learning algorithms calculate how much the features you were introduced to on the previous pages increase or decrease the mean price of a condo in a given New York location. 
When you click on the map and adjust the sliders the page gives you a suggested price, this will be an approximation of a likely price in that position with the given parameters."""


def page_9(df):
    return html.Div([
        dbc.Row([
コード例 #24
0
geolocator = Nominatim(user_agent='locator-for-dash-app')

app = Dash(prevent_initial_callbacks=True,
           external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
    html.Div([
        html.P('Insert location search string'),
        dcc.Input(id='location-input', type='text', debounce=True),
        dbc.Button(
            'Search',
            id='search-button',
            color='secondary',
            size='lg',
        )
    ]),
    dl.Map([dl.TileLayer(), dl.LayerGroup(id="layer")],
           id="map",
           style={
               'width': '20%',
               'height': '50vh',
               'margin': "auto",
               "display": "block"
           }),
    html.P(id='coordinates-display'),
])


@app.callback(
    Output("layer", "children"),
    Output("coordinates-display", "children"),
    Input("search-button", "n_clicks"),
コード例 #25
0
ファイル: geoplot.py プロジェクト: cemac/BiB_extract
markers = [
    dl.CircleMarker(dl.Tooltip(str(row)),
                    center=[row[1].LAT, row[1].LON],
                    radius=25 * row[1][what] / mx,
                    stroke=True,
                    weight=1,
                    color='red',
                    fillColor=cols[row[1]['cat']],
                    fillOpacity=0.7) for row in df.iterrows()
]

#fillColor
#color fillOpacity

app = dash.Dash()
app.layout = html.Div(
    id="BornInBradford",
    children=dl.Map(
        [dl.TileLayer(), dl.LayerGroup(markers, id='markers')],
        center=mid,
        zoom=13,
        style={
            'width': '100%',
            'height': '100vh',
            'margin': "auto",
            "display": "block"
        }))

if __name__ == '__main__':
    app.run_server(debug=True)
コード例 #26
0
ファイル: alerts.py プロジェクト: pyronear/pyro-platform
def build_alerts_elements(images_url_live_alerts, live_alerts, map_style):
    """
    This function is used in the main.py file to create alerts-related elements such as the alert button (banner)
    or the alert markers on the map.

    It takes as arguments:

    - 'images_url_live_alerts': url dict with live_alerts urls having event_id keys
    - 'live_alerts': json containing live_alerts data
    - 'map_style': the type of map in place, either 'alerts' or 'risks'.

    All these inputs are instantiated in the main.py file via a POST from the API.

    In the base case, the function returns:

    - the urls addresses of the image to be displayed on the left of the map;

    - the new_alert_button;

    - the alert markers displayed on the map;

    - new navbar_color as in alert mode;

    - new navbar title;

    - a list of individual storage components, one for each alert/event to be displayed, that give the URL addresses of
    the corresponding frames.

    But if the style of map in place is 'risks', we don't want to display neither the alert markers.
    So in this case, the third output of the function is a void string.
    """

    # Changing the navabar color and title
    navbar_color = "#f34848"
    navbar_title = "Départs de feux détectés"

    # Format of the alert marker icon
    icon = {
        "iconUrl": '../assets/pyro_alert_icon.png',
        "iconSize": [50, 50],  # Size of the icon
        "iconAnchor": [
            25, 45
        ],  # Point of the icon which will correspond to marker's and popup's location
        "popupAnchor":
        [0, -20
         ]  # Point from which the popup should open relative to the iconAnchor
    }

    # Building the list of alert markers to be displayed
    alerts_markers = []
    live_alerts_check = json.loads(live_alerts)

    if ((isinstance(live_alerts_check, dict)
         and 'status' in live_alerts_check.keys()
         and live_alerts_check['status'] == 'never_loaded_alerts_data')
            or not live_alerts_check):
        # When there is no live alert to display, we return a alert header button that will remain hidden
        hidden_header_alert_button = html.Div(
            html.Button(id=f'alert_button_{map_style}'),
            style={'display': 'none'})

        # This is to ensure that the "click_new_alerts_button" callback gets triggered with n_clicks=0 and hides the
        # blank user selection area, letting the map take the full width of the screen

        # (It can be interesting to test returning [] instead of [hidden_header_alert_button] and erase all alerts one
        # by one if explanations are unclear)

        return [hidden_header_alert_button
                ], [], '#054546', 'Surveillez les départs de feux'

    else:
        all_alerts = pd.read_json(live_alerts)

    all_events = all_alerts.drop_duplicates(
        ['id', 'event_id']).groupby('event_id').head(1)  # Get unique events
    for _, row in all_events.iterrows():
        alert_id = str(row['event_id'])
        alert_lat = row['lat']
        alert_lon = row['lon']

        alerts_markers.append(
            dl.Marker(
                id={
                    'type': 'alert_marker',
                    'index': alert_id
                },  # Setting a unique id for each alert marker
                position=(alert_lat, alert_lon),
                icon=icon))

    # Wrapping all markers in the list into a dl.LayerGroup object
    alerts_markers_layer = dl.LayerGroup(children=alerts_markers,
                                         id='alerts_markers')

    # Building the alerts notification btn
    nb_alerts = len(all_events)  # Number of unique events
    alert_button = html.Div(dbc.Button(
        "Nouvelles alertes | {}".format(nb_alerts),
        className="btn-header-alerts"),
                            id=f'alert_button_{map_style}',
                            style={
                                'position': 'absolute',
                                'top': '10px',
                                'right': '30px',
                                'z-index': '1000'
                            })

    individual_alert_frame_placeholder_children = []
    for event_id, frame_url_list in images_url_live_alerts.items():

        individual_alert_frame_placeholder_children.append(
            html.Div(id={
                'type': 'individual_alert_frame_storage',
                'index': str(event_id)
            },
                     children=frame_url_list,
                     style={'display': 'none'}))

    return [alert_button, alerts_markers_layer, navbar_color, navbar_title]
コード例 #27
0
def build_historic_markers(dpt_code=None):
    fire_markers = dl.LayerGroup(children=get_old_fire_positions(dpt_code),
                                 id='historic_fires_markers')

    return fire_markers
コード例 #28
0
import pandas
import dash_html_components as html
from dash.dependencies import Input, Output
import numpy as np

csv = pandas.read_csv('./ASC2021_draft.csv', names=[0, 1])
csv_list = csv.values.tolist()
markers = [
    dl.Marker(position=pos, id="marker{}".format(i), draggable=True)
    for i, pos in enumerate(csv_list)
]
app = dash.Dash()

app.layout = html.Div([
    html.Div(dl.Map(
        [dl.TileLayer(), dl.LayerGroup(id="layer"), *markers],
        zoom=4,
        center=(csv_list[0][0], csv_list[0][1])),
             style={
                 'width': '60%',
                 'height': '50vh',
                 'margin': "auto",
                 "display": "block"
             }),
    html.Div(id='clickdata')
])


@app.callback(Output("layer", "children"),
              [Input(marker.id, "position") for marker in markers])
def marker_click(*args):
コード例 #29
0
ファイル: main_app.py プロジェクト: SavOK/YelpTime
                         )
                     ],
                 ),
             ],
         ),
     ],
 ),
 # Column for app graphs and plots
 html.Div(
     className="eight columns div-for-charts bg-grey",
     children=[
         dl.Map(
             dl.Map(
                 [
                     dl.TileLayer(),
                     dl.LayerGroup(id="my-position"),
                     dl.LayerGroup(id="places-markers"),
                 ],
                 id="result-map",
                 style={
                     "width": "100%",
                     "height": "100vh",
                     "margin": "auto",
                     "display": "block",
                 },
                 center=start_point,
                 zoom=10,
             ), ),
         html.Div(
             className="text-padding",
             id="result-text",
コード例 #30
0
ファイル: app.py プロジェクト: davidzyx/ca-wildfire-risk
month_picker_slider2 = dcc.Slider(
    id='month_slider2',
    min=1,
    max=12,
    marks={
        1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December"
    },
    step=1,
    value=1,
)

month_picker_row2 = html.Div(style={'textAlign': 'center', 'padding-bottom':'2rem'}, children=[html.Div(children='Query a Month:'), month_picker_slider2])
th = daq.Thermometer(id = 'th', value=0.00, min=0.00, max=100, showCurrentValue=True, width=20, height=450, label='Risk Percentage')

label_cali_map2 = html.Div(html.H3(''),style={'margin-bottom':5, 'margin-left':5})
cali_map2 = dl.Map([dl.TileLayer(), dl.LayerGroup(id="layer")], id='map-id', style={'width':'100%', 'height':550}, center=[37.219306366090116, -119.66673872628975], zoom=5)
cali_map_subdiv2 = html.Div(id = 'cal-map2',style={'columnCount': 2}, children=[cali_map2, th])
cali_map_div2 = html.Div(id = 'calmap2', children=[label_cali_map2, cali_map_subdiv2])
pred_div2 = html.Div(id = 'pred', children=[month_picker_row2, html.H3(className='county_graph_title', children=[f'Please pick a point from the map below']), cali_map_div2])
# End of Geo Located Based Prediction


# Building App 
app.title = 'Cal Fire Dashboard'
app.layout = html.Div(children=[dcc.Location(id='url', refresh=False), header, navbar, html.Div(id='page-content', children=[prompt_message_container, our_services])])


# Observer Functions

@app.callback(
   dash.dependencies.Output(component_id='desc_heading', component_property='children'), [dash.dependencies.Input('incident_map', 'n_clicks'),