def test_validation(): h = '8a28308280fffff' # invalid hex with pytest.raises(H3CellError): h3.h3_get_base_cell(h) with pytest.raises(H3CellError): h3.h3_get_resolution(h) with pytest.raises(H3CellError): h3.h3_to_parent(h, 9) with pytest.raises(H3CellError): h3.h3_distance(h, h) with pytest.raises(H3CellError): h3.k_ring(h, 1) with pytest.raises(H3CellError): h3.hex_ring(h, 1) with pytest.raises(H3CellError): h3.h3_to_children(h, 11) with pytest.raises(H3CellError): h3.compact({h}) with pytest.raises(H3CellError): h3.uncompact({h}, 10)
def test_h3_set_to_multi_polygon_2k_ring(): h = '8930062838bffff' hexes = h3.k_ring(h, 2) # multi_polygon mp = h3.h3_set_to_multi_polygon(hexes) assert len(mp) == 1 # polygon count matches expected assert len(mp[0]) == 1 # loop count matches expected assert len(mp[0][0]) == 6 * (2 * 2 + 1) # coord count matches expected hexes2 = { '89300628393ffff', '89300628383ffff', '89300628397ffff', '89300628067ffff', '89300628387ffff', '893006283bbffff', '89300628313ffff', '893006283cfffff', '89300628303ffff', '89300628317ffff', '8930062839bffff', h, '8930062806fffff', '8930062838fffff', '893006283d3ffff', '893006283c3ffff', '8930062831bffff', '893006283d7ffff', '893006283c7ffff' } mp2 = h3.h3_set_to_multi_polygon(hexes2) assert len(mp2) == 1 # polygon count matches expected assert len(mp2[0]) == 1 # loop count matches expected assert len(mp2[0][0]) == 6 * (2 * 2 + 1) # coord count matches expected hexes3 = list(h3.k_ring(h, 6)) hexes3.sort() mp3 = h3.h3_set_to_multi_polygon(hexes3) assert len(mp3[0]) == 1 # loop count matches expected
def test_hex_ring(): h = '8928308280fffff' out = h3.hex_ring(h, 1) expected = { '8928308280bffff', '89283082807ffff', '89283082877ffff', '89283082803ffff', '89283082873ffff', '8928308283bffff', } assert out == expected assert out == h3.k_ring(h, 1) - h3.k_ring(h, 0)
def get_exposure(events, attack_type, p, freq): """ """ cells = [] for country in p.countries: cells += list(json_to_h3(country, p.h3_level)) cells_coord = np.array( [[h3.h3_to_geo(c)[0], h3.h3_to_geo(c)[1]] for c in cells], dtype='float64') events_of_type = events[events["type"] == attack_type] events_coord = events_of_type[["latitude", "longitude"]].to_numpy(dtype='float64') events_h3 = events_of_type["h3"].to_numpy() rings = np.array([list(h3.k_ring(str(cell), 2)) for cell in cells], dtype='object') is_in_ring = np.array([np.isin(events_h3, ring) for ring in rings]) date_range = pd.date_range(p.startdate, p.enddate, freq=freq) date_range = ((date_range - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")).to_numpy() events_dates = ((events["date_start"] - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")).to_numpy() distances = calc_distances(cells_coord, events_coord, is_in_ring) g = get_exposure_raw(events_dates, is_in_ring, distances, date_range) return pd.DataFrame(g, index=cells, columns=pd.to_datetime(date_range, unit="s"))
def test_k_ring2(): h = '8928308280fffff' out = h3.k_ring(h, 2) assert len(out) == 1 + 6 + 12 expected = { '89283082813ffff', '89283082817ffff', '8928308281bffff', '89283082863ffff', '89283082823ffff', '89283082873ffff', '89283082877ffff', h, '8928308287bffff', '89283082833ffff', '8928308282bffff', '8928308283bffff', '89283082857ffff', '892830828abffff', '89283082847ffff', '89283082867ffff', '89283082803ffff', '89283082807ffff', '8928308280bffff', } assert out == expected
def cell_exposure_at_t(events, attack_type, origin, date, distances): """ Calcule l'exposition à date de la cellule origin aux events de type attack_type. """ ring = h3.k_ring(origin, 2) c_events = events.loc[(events['h3'].isin(ring)) & ( events['type'] == attack_type )].copy( ) # On copie https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy # Calculate wa def calc_event_age(row): return date - row['date_start'] def calc_wa(row): if row['age'].days < 0: # L'évènement n'a pas encore eu lieu, on ne le prend pas en compte return 0 return wa(row['age'].days) c_events['age'] = c_events.apply(calc_event_age, axis=1, result_type='reduce') c_events['wa'] = c_events.apply(calc_wa, axis=1, result_type='reduce') wd_df = distances[origin].loc[(events['h3'].isin(ring)) & (events['type'] == attack_type)] return np.dot(wd_df, c_events['wa'])
def calc_distances(cells, events): distances = pd.DataFrame(index=events.index) distances['h3'] = events['h3'].copy() def calc_event_distance(origin, row): cell_lat, cell_lng = h3.h3_to_geo(origin) ev_lat, ev_lng = row['latitude'], row['longitude'] return harvesine(cell_lng, cell_lat, ev_lng, ev_lat) for cell in cells: ring = h3.k_ring(cell, 2) c_events = events.loc[(events['h3'].isin(ring))].copy() c_events['distance'] = c_events.apply( lambda row: calc_event_distance(cell, row), axis=1, result_type='reduce') c_events['wd'] = c_events.apply(lambda row: wd(row['distance']), axis=1, result_type='reduce') #distances[cell] = c_events['distance'] distances[cell] = c_events['wd'] return distances.drop('h3', axis=1)
def test_many_hex_ranges2(): hexes = h3.k_ring('8928308280fffff', 5) out = h3.hex_ranges(hexes, 5) assert len(out) == 91 hexes = out['8928308280fffff'] assert [len(x) for x in hexes] == [1, 6, 12, 18, 24, 30]
def test_many_hex_ranges(): hexes = h3.k_ring('8928308280fffff', 2) out = h3.hex_ranges(hexes, 2) assert len(out) == 19 hexes = out['8928308280fffff'] assert [len(x) for x in hexes] == [1, 6, 12]
def test5(): expected = { '89283082873ffff', '89283082877ffff', '8928308283bffff', '89283082807ffff', '8928308280bffff', '8928308280fffff', '89283082803ffff' } out = h3.k_ring('8928308280fffff', 1) assert out == expected
def test_h3_set_to_multi_polygon(): h = '8928308280fffff' hexes = h3.k_ring(h, 1) mpoly = h3.h3_set_to_multi_polygon(hexes) out = h3.polyfill_polygon(mpoly[0][0], 9, holes=None, lnglat_order=False) assert out == hexes
def test_hex_ring2(): h = '8928308280fffff' out = h3.hex_ring(h, 2) expected = { '89283082813ffff', '89283082817ffff', '8928308281bffff', '89283082863ffff', '89283082823ffff', '8928308287bffff', '89283082833ffff', '8928308282bffff', '89283082857ffff', '892830828abffff', '89283082847ffff', '89283082867ffff', } assert out == expected assert out == h3.k_ring(h, 2) - h3.k_ring(h, 1)
def fit_model(self, simulation_file: str, k_ring_factor: float = 0.4, k_k_ring: float = 1): sim_data = pd.read_csv(f'simulations/{simulation_file}', parse_dates=['timestamp']) # regular_sampling for time series analysis sim_data_reg = pd.DataFrame( sim_data.groupby(['hex']).resample('5T', on='timestamp')['lat'].count()) sim_data_reg.reset_index(inplace=True) sim_data_reg.rename(columns={'lat': 'dem'}, inplace=True) #k-ring "convolution" for hex_id in sim_data_reg.hex.unique(): # data from hexagon hex_data = sim_data_reg[sim_data_reg.hex == hex_id].copy() # data from kring kring_hex_list = [ hex for hex in h3.k_ring(hex_id, k=k_k_ring) if hex != hex_id ] kring_data = sim_data_reg[sim_data_reg.hex.isin(kring_hex_list)] kring_data_agg = kring_data.groupby('timestamp', as_index=False).dem.sum() kring_data_agg.rename(columns={'dem': 'kring_dem'}, inplace=True) # merge both hex_data_kring = pd.merge(left=hex_data, right=kring_data_agg, how='outer', on='timestamp') hex_data_kring.fillna({ 'hex': hex_id, 'dem': 0, 'kring_dem': 0 }, inplace=True) # build ponderate demand hex_data_kring['y'] = hex_data_kring['dem'] * ( 1 - k_ring_factor) + (hex_data_kring['kring_dem'] * k_ring_factor) # fit hex model hex_model = self.fit_hex_model(hex_data_kring) self.model_dict[hex_id] = hex_model self.is_fitted = True
def test_k_ring_pentagon(): h = '821c07fffffffff' # a pentagon cell out = h3.k_ring(h, 1) assert len(out) == 1 + 5 expected = { '821c2ffffffffff', '821c27fffffffff', h, '821c17fffffffff', '821c1ffffffffff', '821c37fffffffff', } assert out == expected
def cell_exposure_at_t_with_cas(events, attack_type, origin, date, distances): """ Calcule l'exposition à date de la cellule origin aux events de type attack_type en prenant en compte le nombre de victimes ("cas" = casualties). """ ring = h3.k_ring(origin, 2) c_events = events.loc[(events['h3'].isin(ring)) & ( events['type'] == attack_type )].copy( ) # On copie https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy # Calculate wa def calc_event_age(row): return date - row['date_start'] def calc_wa(row): if row['age'].days < 0: # L'évènement n'a pas encore eu lieu, on ne le prend pas en compte return 0 return wa(row['age'].days) c_events['age'] = c_events.apply(calc_event_age, axis=1, result_type='reduce') c_events['wa'] = c_events.apply(calc_wa, axis=1, result_type='reduce') # Fetch wd wd_df = distances[origin].loc[(events['h3'].isin(ring)) & (events['type'] == attack_type)] # Calculate wcas def calc_wcas(row): # On regarde le nombre moyen de victimes sur les trois derniers mois recent_events = c_events.loc[(c_events['age'].dt.days >= 0) & (c_events['age'].dt.days <= 90)] mean = recent_events['fatalities'].mean() return wcas(mean, row['fatalities']) c_events['wcas'] = c_events.apply(calc_wcas, axis=1, result_type='reduce') c_events.fillna(c_events['wcas'].mean(), inplace=True) return np.dot(wd_df, c_events['wa'] * c_events['wcas'])
def test_k_ring(): h = '8928308280fffff' out = h3.k_ring(h, 1) assert len(out) == 1 + 6 expected = { '8928308280bffff', '89283082807ffff', '89283082877ffff', h, '89283082803ffff', '89283082873ffff', '8928308283bffff', } assert out == expected
def filter_h3d_around(cls, lat, lon, res, k_distance=1, queryset=None): """ Filter all instances with the same h3 cell, or in cells around it :param lat: latitude :param lon: longitude :param res: resolution (level, depth) of the index where to find :param k_distance: max distance in hexagon cells from the cell containing the start point 0 for the containing cell only, 1 for the containing cell and cells immediately around, etc. :param queryset: the queryset to search in, None means cls.objects.all() """ cells = h3.compact(h3.k_ring(h3.geo_to_h3(lat, lon, res), k_distance)) d_cells = [h3d.h3s_to_h3d(c) for c in cells] filters = [models.Q(h3d__range=h3d.h3d_range(c)) for c in d_cells] if not queryset: queryset = cls.objects.all() return queryset.filter(functools.reduce(operator.or_, filters))
def test_k_ring_distance(): with pytest.raises(H3DistanceError): h3.k_ring('8928308280fffff', -10)
def create_smother_demand_mapper( hex_cluster: List[str], day_intervals: [str, dict] = 'default', hex_with_high_demand: [str, dict] = 'default', cat_lambda_map: [str, dict] = 'default', ) -> Dict[Tuple[str, int], float]: if day_intervals == 'default': day_intervals_dict = { 'morning': [7, 10], 'mid_morning': [11, 15], 'afternoon': [16, 18], 'night': [19, 22] } else: day_intervals_dict = deepcopy(day_intervals) if hex_with_high_demand == 'default': hex_with_high_demand_dict = { 'morning': 1, 'mid_morning': 3, 'afternoon': 1, 'night': 3 } else: hex_with_high_demand_dict = deepcopy(hex_with_high_demand) if cat_lambda_map == 'default': cat_lambda_map_dict = { 'low_demand': 900, # time in minutes 'mid_demand': 360, 'high_demand': 120, } else: cat_lambda_map_dict = deepcopy(cat_lambda_map) demand_map_sim = {} for day_window in day_intervals_dict.keys(): # select n peaks hex_peak_list = random.sample(hex_cluster, hex_with_high_demand_dict[day_window]) # expand n peaks to k ring = 2 hex_high_demand = set(hex_peak_list) for high_peak_hex in hex_peak_list: neighborhood = h3.k_ring(high_peak_hex, k=1) hex_high_demand.update(neighborhood) # expand to mid_demand hex_mid_demand = set() for high_peak_hex in hex_high_demand: neighborhood = h3.k_ring(high_peak_hex, k=2) outer_hex = set(neighborhood).difference(hex_high_demand) hex_mid_demand.update(outer_hex) # iterate over hours window_low_bound = day_intervals_dict[day_window][0] window_up_bound = day_intervals_dict[day_window][1] + 1 for hour in range(window_low_bound, window_up_bound): for hex in hex_cluster: if hex in hex_high_demand: demand_map_sim[tuple( [hex, hour])] = cat_lambda_map_dict['high_demand'] elif hex in hex_mid_demand: demand_map_sim[tuple( [hex, hour])] = cat_lambda_map_dict['mid_demand'] else: demand_map_sim[tuple( [hex, hour])] = cat_lambda_map_dict['low_demand'] return demand_map_sim
def poc_polar(hotspot, chals): H = Hotspots() haddr = hotspot['address'] hlat, hlng = hotspot['lat'], hotspot['lng'] hname = hotspot['name'] if os.path.exists(hname): files = glob(hname + '\\*') for file in files: os.remove(file) else: os.mkdir(hname) wl = {} #witnesslist rl = { } #received list of hotspots(hotspot of intereset has been witness to these or received from them) c = 299792458 for chal in chals: # loop through challenges for p in chal['path']: #path? if p['challengee'] == haddr: # handles cases where hotspot of interest is transmitting for w in p[ 'witnesses']: #loop through witnesses so we can get rssi at each location challenge received #print('witness',w) lat = H.get_hotspot_by_addr(w['gateway'])['lat'] lng = H.get_hotspot_by_addr(w['gateway'])['lng'] name = H.get_hotspot_by_addr(w['gateway'])['name'] dist_km, heading = utils.haversine_km(hlat, hlng, lat, lng, return_heading=True) fspl = 20 * log10((dist_km + 0.01) * 1000) + 20 * log10( 915000000) + 20 * log10(4 * pi / c) - 27 try: wl[w['gateway']]['lat'] = lat wl[w['gateway']]['lng'] = lng wl[w['gateway']]['rssi'].append(w['signal']) except KeyError: wl[w['gateway']] = { 'rssi': [ w['signal'], ], 'dist_km': dist_km, 'heading': heading, 'fspl': fspl, 'lat': lat, 'lng': lng, 'name': name } else: # hotspot of interest is not transmitting but may be a witness challengee = p['challengee'] name = H.get_hotspot_by_addr(challengee)['name'] for w in p['witnesses']: if w['gateway'] != haddr: continue #print('transmitter ', name) #print('witness ', H.get_hotspot_by_addr(w['gateway'])['name']) # hotspot of interest was a witness lat = H.get_hotspot_by_addr(challengee)['lat'] lng = H.get_hotspot_by_addr(challengee)['lng'] #name=H.get_hotspot_by_addr(w['gateway'])['name'] dist_km, heading = utils.haversine_km(hlat, hlng, lat, lng, return_heading=True) fspl = 20 * log10((dist_km + 0.01) * 1000) + 20 * log10( 915000000) + 20 * log10(4 * pi / c) - 27 try: rl[challengee]['lat'] = lat rl[challengee]['lng'] = lng rl[challengee]['rssi'].append(w['signal']) except KeyError: rl[challengee] = { 'rssi': [ w['signal'], ], 'dist_km': dist_km, 'heading': heading, 'fspl': fspl, 'lat': lat, 'lng': lng, 'name': name } #print('rl:',rl) ratios = [1.0] * 16 rratios = [1.0] * 16 N = len(ratios) - 1 angles = [] rangles = [] #angles = [n / float(N) *2 *pi for n in range(N+1)] angles = list(np.arange(0.0, 2 * np.pi + (2 * np.pi / N), 2 * np.pi / N)) rangles = list(np.arange(0.0, 2 * np.pi + (2 * np.pi / N), 2 * np.pi / N)) #print(angles,len(angles)) #print(ratios,len(ratios)) markers = [] encoded = {} rencoded = {} for w in wl: #for witness in witnesslist #print(wl[w]) mean_rssi = sum(wl[w]['rssi']) / len(wl[w]['rssi']) ratio = wl[w]['fspl'] / mean_rssi * (-1) if ratio > 3.0: ratio = 3.0 elif ratio < -3.0: ratio = -3.0 ratios.append(ratio) angles.append(wl[w]['heading'] * pi / 180) #markers.append(folium.Marker([wl[w]['lat'],wl[w]['lng']],popup=wl[w]['name'])) markers.append([[wl[w]['lat'], wl[w]['lng']], wl[w]['name']]) # the histogram of the data #unique=set(wl[w]['rssi']) #num_unique=len(unique) n, bins, patches = plt.hist( wl[w]['rssi'], 10) #, density=True, facecolor='g', alpha=0.75,) plt.xlabel('RSSI(dB)') plt.ylabel('Count(Number of Packets)') wit = str(wl[w]['name']) plt.title('Packets from ' + hname + ' measured at ' + wit) #plt.text(60, .025, r'$\mu=100,\ \sigma=15$') #plt.xlim(40, 160) #plt.ylim(0, 0.03) plt.grid(True) #plt.show() strFile = str(wl[w]['name']) + '.jpg' strWitness = str(wl[w]['name']) if os.path.isfile(strFile): #print('remove') os.remove(strFile) # Opt.: os.system("rm "+strFile) plt.savefig(hname + '//' + strFile) encoded[strWitness] = base64.b64encode( open(hname + '//' + strFile, 'rb').read()) plt.close() for w in rl: #for witness in witnesslist #print(rl[w]) mean_rssi = sum(rl[w]['rssi']) / len(rl[w]['rssi']) rratio = rl[w]['fspl'] / mean_rssi * (-1) if rratio > 3.0: rratio = 3.0 elif rratio < -3.0: rratio = -3.0 rratios.append(rratio) rangles.append(rl[w]['heading'] * pi / 180) #markers.append([[wl[w]['lat'],wl[w]['lng']],wl[w]['name']]) n, bins, patches = plt.hist( rl[w]['rssi'], 10) #, density=True, facecolor='g', alpha=0.75,) plt.xlabel('RSSI(dB)') plt.ylabel('Count(Number of Packets)') wit = str(rl[w]['name']) plt.title('Packets from ' + wit + ' measured at ' + hname) plt.grid(True) #plt.show() strFile = 'rrr' + str(rl[w]['name']) + '.jpg' strWitness = str(rl[w]['name']) if os.path.isfile(strFile): #print('remove') os.remove(strFile) # Opt.: os.system("rm "+strFile) plt.savefig(hname + '//' + strFile) rencoded[strWitness] = base64.b64encode( open(hname + '//' + strFile, 'rb').read()) plt.close() # create polar chart angles, ratios = zip(*sorted(zip(angles, ratios))) rangles, rratios = zip(*sorted(zip(rangles, rratios))) angles, ratios = (list(t) for t in zip(*sorted(zip(angles, ratios)))) rangles, rratios = (list(t) for t in zip(*sorted(zip(rangles, rratios)))) fig, ax = plt.subplots(subplot_kw=dict(projection='polar')) ax.set_theta_zero_location("N") ax.set_theta_direction(-1) #ax.set_rmax(3) #ax.set_rmin(-3) ax.set_ylim(-3, 3) ax.plot(angles, ratios, marker='^', linestyle='solid', color='tomato', linewidth=2, markersize=5, label='Transmitting') #markerfacecolor='m', markeredgecolor='k', ax.plot(rangles, rratios, marker='v', linestyle='solid', color='dodgerblue', linewidth=1, markersize=5, label='Receiving') #, markerfacecolor='m', markeredgecolor='k' ax.legend(bbox_to_anchor=(0, 1), fancybox=True, framealpha=0, loc="lower left", facecolor='#000000') plt.xlabel('FSPL/RSSI') plt.savefig(hname + '//' + hname + '.png', transparent=True) #plt.show() # add polar chart as a custom icon in map m = folium.Map([hlat, hlng], tiles='stamentoner', zoom_start=18, control_scale=True, max_zoom=20) polargroup = folium.FeatureGroup(name='Polar Plot') icon = folium.features.CustomIcon(icon_image=hname + '//' + hotspot['name'] + '.png', icon_size=(640, 480)) marker = folium.Marker([hlat, hlng], popup=hotspot['name'], icon=icon) polargroup.add_child(marker) # add witness markers hsgroup = folium.FeatureGroup(name='Witnesses') hsgroup.add_child(folium.Marker([hlat, hlng], popup=hotspot['name'])) # add the witness markers for marker in markers: #html = '<img src="data:image/jpg;base64,{}">'.format html = '<p><img src="data:image/jpg;base64,{}" alt="" width=640 height=480 /></p> \ <p><img src="data:image/jpg;base64,{}" alt="" width=640 height=480 /></p>'.format #print('marker',marker) try: iframe = IFrame(html(encoded[marker[1]].decode('UTF-8'), rencoded[marker[1]].decode('UTF-8')), width=640 + 25, height=960 + 40) popup = folium.Popup(iframe, max_width=2650) mark = folium.Marker(marker[0], popup=popup) hsgroup.add_child(mark) except KeyError: # this means this witness never heard from us so there is no marker for it pass # not sure where to put the receive packet histogram so just ignore for now radius = 0.01 center = Point(hlat, hlng) circle = center.buffer(radius) # Degrees Radius gjcircle = shapely.geometry.mapping(circle) circle = center.buffer(radius * 25) # Degrees Radius gjcircle8 = shapely.geometry.mapping(circle) dcgroup = folium.FeatureGroup(name='Distance Circles', show=False) radius = 0.01 center = Point(hlat, hlng) circle = center.buffer(radius) # Degrees Radius gjcircle = shapely.geometry.mapping(circle) circle = gjcircle['coordinates'][0] my_Circle = folium.Circle(location=[hlat, hlng], radius=300, popup='300m', tooltip='300m') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=1000, popup='1km', tooltip='1km') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=2000, popup='2km', tooltip='2km') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=3000, name='circles', popup='3km', tooltip='3km') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=4000, popup='4km', tooltip='4km') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=5000, popup='5km', tooltip='5km') dcgroup.add_child(my_Circle) my_Circle = folium.Circle(location=[hlat, hlng], radius=10000, popup='10km', tooltip='10km') dcgroup.add_child(my_Circle) h3colorgroup = folium.FeatureGroup(name='h3 Hexagon Grid Color Fill', show=False) style = {'fillColor': '#f5f5f5', 'lineColor': '#ffffbf'} #polygon = folium.GeoJson(gjson, style_function = lambda x: style).add_to(m) h3group = folium.FeatureGroup(name='h3 r11 Hex Grid', show=False) h3namegroup = folium.FeatureGroup(name='h3 r11 Hex Grid Names', show=False) h3fillgroup = folium.FeatureGroup(name='h3 r11 Hex Grid Color Fill', show=True) h3r8namegroup = folium.FeatureGroup(name='h3 r8 Hex Grid Names', show=False) h3r8group = folium.FeatureGroup(name='h3 r8 Hex Grid', show=False) hexagons = list(h3.polyfill(gjcircle, 11)) hexagons8 = list(h3.polyfill(gjcircle8, 8)) polylines = [] lat = [] lng = [] i = 0 #print('hexagon',hexagons[0]) #print(dir(h3)) home_hex = h3.geo_to_h3(hlat, hlng, 11) a = h3.k_ring(home_hex, 7) for h in a: gjhex = h3.h3_to_geo_boundary(h, geo_json=True) gjhex = geometry.Polygon(gjhex) mean_rsrp = -60 folium.GeoJson( gjhex, style_function=lambda x, mean_rsrp=mean_rsrp: { 'fillColor': map_color_rsrp(mean_rsrp), 'color': map_color_rsrp(mean_rsrp), 'weight': 1, 'fillOpacity': 0.5 }, #tooltip='tooltip' ).add_to(h3fillgroup) for hex in hexagons: p2 = h3.h3_to_geo(hex) #p2 = [45.3311, -121.7113] folium.Marker( p2, name='hex_names', icon=DivIcon( #icon_size=(150,36), #icon_anchor=(35,-45), icon_anchor=(35, 0), html='<div style="font-size: 6pt; color : black">' + str(hex) + '</div>', )).add_to(h3namegroup) #m.add_child(folium.CircleMarker(p2, radius=15)) polygons = h3.h3_set_to_multi_polygon([hex], geo_json=False) # flatten polygons into loops. outlines = [loop for polygon in polygons for loop in polygon] polyline = [outline + [outline[0]] for outline in outlines][0] lat.extend(map(lambda v: v[0], polyline)) lng.extend(map(lambda v: v[1], polyline)) polylines.append(polyline) for polyline in polylines: my_PolyLine = folium.PolyLine(locations=polyline, weight=1, color='blue') h3group.add_child(my_PolyLine) polylines = [] lat = [] lng = [] #polylines8 = [] for hex in hexagons8: p2 = h3.h3_to_geo(hex) folium.Marker( p2, name='hex_names', icon=DivIcon( #icon_size=(150,36), #icon_anchor=(35,-45), icon_anchor=(35, 0), html='<div style="font-size: 8pt; color : black">' + str(hex) + '</div>', )).add_to(h3r8namegroup) polygons = h3.h3_set_to_multi_polygon([hex], geo_json=False) # flatten polygons into loops. outlines = [loop for polygon in polygons for loop in polygon] polyline = [outline + [outline[0]] for outline in outlines][0] lat.extend(map(lambda v: v[0], polyline)) lng.extend(map(lambda v: v[1], polyline)) polylines.append(polyline) for polyline in polylines: my_PolyLine = folium.PolyLine(locations=polyline, weight=1, color='blue') h3r8group.add_child(my_PolyLine) # add possible tiles folium.TileLayer('cartodbpositron').add_to(m) folium.TileLayer('cartodbdark_matter').add_to(m) folium.TileLayer('openstreetmap').add_to(m) folium.TileLayer('Mapbox Bright').add_to(m) #folium.TileLayer('stamentoner').add_to(m) # add markers layer #marker_cluster = MarkerCluster().add_to(m) polargroup.add_to(m) #polar plot hsgroup.add_to(m) #hotspots dcgroup.add_to(m) #distance circles h3group.add_to(m) h3namegroup.add_to(m) h3fillgroup.add_to(m) m.keep_in_front(h3group) h3r8group.add_to(m) h3r8namegroup.add_to(m) # add the layer control folium.LayerControl(collapsed=False).add_to(m) m.save(hname + '//' + hname + '_map.html')