def get_cell_ids_h3(lat:float, lng:float, angle: float) -> List: p = shapely.geometry.Point([lng, lat]) # so to more accurately match projections maybe arc length of a sphere woulde be best? arc_length = R_MEAN * angle # in km n_points = 20 #arc_length should be the radius in kilometers so convert to diameter in meters d = arc_length * 1000 # meters angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) try: mapping = shapely.geometry.mapping(shapely.geometry.Polygon(polygon)) except ValueError as e: print(f"lat:{lat}, lng:{lng}") print(polygon) cells = h3.polyfill(mapping, H3_RESOLUTION_LEVEL, True) return cells
def polyfill(): import h3 # 1. Definit le polygon à remplir en geojson # # En geojson: # -les polygons sont décris dans le sens inverse des aiguilles d'une montre # - le premier point doit-être répété à la fin. # - les points sont décris comme un tableau en 3 dimensions # [[[latitude, longitude]]] polygon_geojson = { "type": "Polygon", "coordinates": [[ [2.25, 48.82], # point0: sud ouest de Paris [2.40, 48.82], # point1: sud est de Paris [2.40, 48.89], # point2: nord est de Paris [2.25, 48.89], # point3: nord ouest de Paris [2.25, 48.82], # point4: sud ouest de Paris ]], } # 2. Appelle polyfill geocodes = h3.polyfill(geojson=polygon_geojson, res=8, geo_json_conformant=True) # 3. Affiche les resultat print(set(list(geocodes)[0:10])) print("") # returns { "881fb46755fffff", "881fb475a7fffff", "881fb46639fffff", "881fb46739fffff", "881fb46601fffff", "881fb475abfffff", "881fb46441fffff", "881fb4660dfffff", "881fb4674dfffff", "881fb4666dfffff", }
def json_to_h3(country, res): """ Remplit une surface avec des hexagones. Parameters ---------- country : str res : int Résolution H3, entre 1 et 16 Returns ------- Liste des identifiants des cellules H3 remplissant la surface. """ path = f"../GeoJSONs/{country}.geo.json" fObj = open(path) s = json.load(fObj) s = s['features'][0]['geometry'] swap_lng_lat(s) return h3.polyfill(s, res=res)
def test_compact_and_uncompact(): geo = { 'type': 'Polygon', 'coordinates': [ [ [37.813318999983238, -122.4089866999972145], [37.7866302000007224, -122.3805436999997056], [37.7198061999978478, -122.3544736999993603], [37.7076131999975672, -122.5123436999983966], [37.7835871999971715, -122.5247187000021967], [37.8151571999998453, -122.4798767000009008], ] ] } hexes = h3.polyfill(geo, 9) compact_hexes = h3.compact(hexes) assert len(compact_hexes) == 209 uncompact_hexes = h3.uncompact(compact_hexes, 9) assert len(uncompact_hexes) == 1253
def fill_hexagons(geom_geojson, res, flag_swap=False, flag_return_df=False): """Fill the input polygons with h3 hexagons. The result of each polygon is stored in a single dataframe item. Note: Each time you execute this function, the set of hexagons is the same, but the sequence order is different.""" set_hexagons = h3.polyfill(geojson=geom_geojson, res=res, geo_json_conformant=flag_swap) list_hexagons_filling = list(set_hexagons) if flag_return_df is True: df_fill_hex = pd.DataFrame({"hex_id": list_hexagons_filling}) df_fill_hex["geometry"] = df_fill_hex.hex_id.apply( lambda x: {"type": "Polygon", "coordinates": [ h3.h3_to_geo_boundary(h=x, geo_json=True) ] }) assert (df_fill_hex.shape[0] == len(list_hexagons_filling)) return df_fill_hex else: return list_hexagons_filling
def test_polyfill_with_hole(): geo = { 'type': 'Polygon', 'coordinates': [ [ [37.813318999983238, -122.4089866999972145], [37.7866302000007224, -122.3805436999997056], [37.7198061999978478, -122.3544736999993603], [37.7076131999975672, -122.5123436999983966], [37.7835871999971715, -122.5247187000021967], [37.8151571999998453, -122.4798767000009008], ], [ [37.7869802, -122.4471197], [37.7664102, -122.4590777], [37.7710682, -122.4137097], ] ] } out = h3.polyfill(geo, 9) assert len(out) > 1000
def fill_hex_grid(gdf: gpd.GeoDataFrame, geom_column: str = "geometry") -> gpd.GeoDataFrame: bbox = gdf.total_bounds # Pandas somehow mangles Geopandas geometry column types so that the types # become mixed after concatenation and may cause TypeErrors, i.e. some # Shapely geometries may be cast as strings in the process. We have to # concatenate regular dataframes instead and reconstruct a geodataframe # from the hex indices afterwards. Utterly stupid. df = gdf.drop(columns=['geometry']) bbox_polygon = box(*bbox) hex_column = next((col for col in df.columns if col.startswith("hex")), False) if not hex_column: raise AssertionError( "Cannot calculate clusters, hex column not found.") resolution = int(hex_column.replace("hex", "")) # H3 polyfill needs geojson-like stuff. geo_json_conformant switches coordinate order hexes_in_bbox = h3.polyfill(mapping(bbox_polygon), resolution, geo_json_conformant=True) # Add only missing hexes here missing_hexes = set(hexes_in_bbox).difference(df[hex_column]) missing_df = pd.DataFrame(list(missing_hexes), columns=[hex_column]).set_index(hex_column, drop=False) columns_to_add = df.columns.difference(missing_df.columns) for column in columns_to_add: # Just add zeroes for missing index values missing_df.insert(0, column, 0) combined_df = pd.concat((df, missing_df)) # Add centroid geometries and reconstruct the geodataframe centroid_lat_lon = [h3.h3_to_geo(hex) for hex in combined_df[hex_column]] centroids = [Point(geom[1], geom[0]) for geom in centroid_lat_lon] combined_gdf = gpd.GeoDataFrame(combined_df) combined_gdf = combined_gdf.set_geometry(centroids) return combined_gdf
map_h3 = folium.Map(location=[40.7, -74], tiles="cartodbpositron", zoom_start=13) folium.GeoJson(data=neighborhoods_pd["geometry"].iloc[0:10]).add_to(map_h3) map_h3.save("source/output.html") map_h3 # COMMAND ---------- # DBTITLE 1,Get H3 Indices that represent the Geometry import shapely import h3 polygon = neighborhoods_pd.iloc[11]["geometry"] geo_json_geom = shapely.geometry.mapping(polygon) indices = h3.polyfill(geo_json_geom, 10, True) list(indices)[0] # COMMAND ---------- # DBTITLE 1,Convert indices to Polygons index_geoms = [h3.h3_to_geo_boundary(ind, True) for ind in indices] index_geoms = [shapely.geometry.Polygon(ind) for ind in index_geoms] # COMMAND ---------- # DBTITLE 1,Folium Style Functions def pink_poly(feature): return { 'fillColor': '#e6328c',
def h3fy(source, resolution=6, clip=False, return_geoms=True): """Generate a hexgrid geodataframe that covers the face of a source geodataframe. Parameters ---------- source : geopandas.GeoDataFrame GeoDataFrame to transform into a hexagonal grid resolution : int, optional (default is 6) resolution of output h3 hexgrid. See <https://h3geo.org/docs/core-library/restable> for more information clip : bool, optional (default is False) if True, hexagons are clipped to the precise boundary of the source gdf. Otherwise, heaxgons along the boundary will be left intact. return_geoms: bool, optional (default is True) whether to generate hexagon geometries as a geodataframe or simply return hex ids as a pandas.Series Returns ------- pandas.Series or geopandas.GeoDataFrame if `return_geoms` is True, a geopandas.GeoDataFrame whose rows comprise a hexagonal h3 grid (indexed on h3 hex id). if `return_geoms` is False, a pandas.Series of h3 hexagon ids """ try: import h3 except ImportError: raise ImportError( "This function requires the `h3` library. " "You can install it with `conda install h3-py` or " "`pip install h3`" ) orig_crs = source.crs if not source.crs.is_geographic: source = source.to_crs(4326) hexids = pandas.Series( list( h3.polyfill( source.unary_union.__geo_interface__, resolution, geo_json_conformant=True, ) ), name="hex_id", ) if not return_geoms: return hexids polys = hexids.apply( lambda hex_id: Polygon(h3.h3_to_geo_boundary(hex_id, geo_json=True)), ) hexs = geopandas.GeoDataFrame(hexids, geometry=polys, crs=source.crs).set_index( "hex_id" ) if clip: hexs = geopandas.clip(hexs, source) if not hexs.crs.equals(orig_crs): hexs = hexs.to_crs(orig_crs) return hexs
def add_baseline_seismicity(folder_name: str, folder_name_out: str, fname_config: str, fname_poly: str, skip=[]): """ :param folder_name: The name of the folder containing the files with GR parameters for the points in each zone considered :param folder_name_out: The folder where to write the results :param config_file: A .toml file with the configuration parameters :param shapefile: The name of the shapefile containing the geometry of the polygons used :param skip: A list with the sources that should be skipped [NOT ACTIVE!!!] :returns: An updated set of .csv files """ # Create output folder create_folder(folder_name_out) # Parsing config model = toml.load(fname_config) h3_level = model['baseline']['h3_level'] basel_agr = model['baseline']['a_value'] basel_bgr = model['baseline']['b_value'] # Read polygons polygons_gdf = gpd.read_file(fname_poly) # Loop over the polygons polygons_gdf.sort_values(by="id", ascending=True, inplace=True) polygons_gdf.reset_index(drop=True, inplace=True) for idx, poly in polygons_gdf.iterrows(): geojson_poly = eval(json.dumps(shapely.geometry.mapping( poly.geometry))) # Revert the positions of lons and lats coo = [[c[1], c[0]] for c in geojson_poly['coordinates'][0]] geojson_poly['coordinates'] = [coo] # Discretizing the polygon i.e. find all the hexagons covering the # polygon describing the current zone hexagons = list(h3.polyfill(geojson_poly, h3_level)) # Read the file with the points obtained by the smoothing print("Source ID", poly.id) fname = os.path.join(folder_name, '{:s}.csv'.format(poly.id)) df = pd.read_csv(fname) srcs_idxs = [ h3.geo_to_h3(la, lo, h3_level) for lo, la in zip(df.lon, df.lat) ] hxg_idxs = [hxg for hxg in hexagons] missing = list(set(hxg_idxs) - set(srcs_idxs)) tmp = np.nonzero([df.agr <= basel_agr])[0] # If we don't miss cells and rates are all above the threshold there # is nothing else to do fname = os.path.join(folder_name_out, "{:s}.csv".format(poly.id)) if len(missing) == 0 and len(tmp) == 0: df.to_csv(fname, index=False) continue # Get the indexes of the point sources with low rates idxs = np.nonzero(df.agr.to_numpy() <= basel_agr)[0] low = [srcs_idxs[i] for i in idxs] # Removing the sources with activity below the threshold df.drop(df.index[idxs], inplace=True) # Find the h3 indexes of the point sources either without seismicity # or with a rate below the baseline both = set(missing) | set(low) # Adding baseline seismicity to the dataframe for the current source if len(both) > 0: tmp_df = create_missing(both, h3_level, basel_agr, basel_bgr) df = df.append(tmp_df) # Creating output file assert len(hxg_idxs) == df.shape[0] df.to_csv(fname, index=False)
def create_from_polygons(self, res: int, polygons: list) -> T: hexes = h3.polyfill(polygons, res=9) return SetH3Hex(res, hexes)
def get_h3_cells(geojson_in, resolution): hexids = list( h3.polyfill(geojson_in, res=resolution, geo_json_conformant=True)) return hexids
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')
def test_polyfill_bogus_geo_json(): with pytest.raises(ValueError): bad_geo = {'type': 'whatwhat'} h3.polyfill(bad_geo, 9)