GeoPandas is a project to add support for geographic data to pandas objects. (See https://github.com/geopandas/geopandas)
It provides (among other cool things) a GeoDataFrame
object that represents a Feature collection.
When you have one, you may be willing to use it on a folium map. Here's the simplest way to do so.
In this example, we'll use the same file as GeoPandas demo ; it's containing the boroughs of New York City.
import geopandas
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
)
nybb = f"{url}/nybb.zip"
boros = geopandas.read_file(nybb)
boros
BoroCode | BoroName | Shape_Leng | Shape_Area | geometry | |
---|---|---|---|---|---|
0 | 5 | Staten Island | 330454.175933 | 1.623847e+09 | MULTIPOLYGON (((970217.022 145643.332, 970227.... |
1 | 3 | Brooklyn | 741227.337073 | 1.937810e+09 | MULTIPOLYGON (((1021176.479 151374.797, 102100... |
2 | 4 | Queens | 896875.396449 | 3.045079e+09 | MULTIPOLYGON (((1029606.077 156073.814, 102957... |
3 | 1 | Manhattan | 358400.912836 | 6.364308e+08 | MULTIPOLYGON (((981219.056 188655.316, 980940.... |
4 | 2 | Bronx | 464475.145651 | 1.186822e+09 | MULTIPOLYGON (((1012821.806 229228.265, 101278... |
To create a map with these features, simply put them in a GeoJson
:
import folium
m = folium.Map([40.7, -74], zoom_start=10, tiles="cartodbpositron")
folium.GeoJson(boros).add_to(m)
m
Quite easy.
Well, you can also take advantage of your GeoDataFrame
structure to set the style of the data. For this, just create a column style
containing each feature's style in a dictionnary.
boros["style"] = [
{"fillColor": "#ff0000", "weight": 2, "color": "black"},
{"fillColor": "#00ff00", "weight": 2, "color": "black"},
{"fillColor": "#0000ff", "weight": 2, "color": "black"},
{"fillColor": "#ffff00", "weight": 2, "color": "black"},
{"fillColor": "#00ffff", "weight": 2, "color": "black"},
]
boros
BoroCode | BoroName | Shape_Leng | Shape_Area | geometry | style | |
---|---|---|---|---|---|---|
0 | 5 | Staten Island | 330454.175933 | 1.623847e+09 | MULTIPOLYGON (((970217.022 145643.332, 970227.... | {'fillColor': '#ff0000', 'weight': 2, 'color':... |
1 | 3 | Brooklyn | 741227.337073 | 1.937810e+09 | MULTIPOLYGON (((1021176.479 151374.797, 102100... | {'fillColor': '#00ff00', 'weight': 2, 'color':... |
2 | 4 | Queens | 896875.396449 | 3.045079e+09 | MULTIPOLYGON (((1029606.077 156073.814, 102957... | {'fillColor': '#0000ff', 'weight': 2, 'color':... |
3 | 1 | Manhattan | 358400.912836 | 6.364308e+08 | MULTIPOLYGON (((981219.056 188655.316, 980940.... | {'fillColor': '#ffff00', 'weight': 2, 'color':... |
4 | 2 | Bronx | 464475.145651 | 1.186822e+09 | MULTIPOLYGON (((1012821.806 229228.265, 101278... | {'fillColor': '#00ffff', 'weight': 2, 'color':... |
m = folium.Map([40.7, -74], zoom_start=10, tiles="cartodbpositron")
folium.GeoJson(boros).add_to(m)
m
Folium should work with any object that implements the __geo_interface__
but be aware that sometimes you may need to convert your data to epsg='4326'
before sending it to folium
.
import fiona
import shapely
fname = f"{url}/2014_08_05_farol.gpx"
with fiona.open(fname, "r", layer="tracks") as records:
tracks = [shapely.geometry.shape(record["geometry"]) for record in records]
track = tracks[0]
m = folium.Map(tiles="cartodbpositron")
folium.GeoJson(track).add_to(m)
m.fit_bounds(m.get_bounds())
m