Willkommen
I stumbled upon a new [to me] python library called Folium
. It’s a mapping tool that enables python developers (or is it programmers, which is less offensive?) to visualize data on a Leaflet map.
About folium
Folium
makes it easy to visualize data that’s been manipulated in Python on an interactive leaflet map. It enables both the binding of data to a map forchoropleth
visualizations as well as passing rich vector/raster/HTML visualizations as markers on the map.The library has a number of built-in tilesets from OpenStreetMap, Mapbox, and Stamen, and supports custom tilesets with Mapbox or Cloudmade API keys.
Folium docsFolium
supports Image/Video, GeoJSON and TopoJSON overlays.
…but what about leaflet.js
?
Leaflet.js “Features” page
Leaflet.js
is the leading open-source JavaScript library for mobile-friendly interactive maps. Out-of-the-box features include: tile layers/WMS, markers/popups, vector layers (polylines, polygons, circles, rectangles), image overlays, and GeoJSON
Tilesets
I highlighted the tilesets above, and I’m not sure if this is a GIS or a leaflet term, but it seems that tilesets refer to different map renderings. Folium includes the following:
- OpenStreetMap
- Stamen Terrain
- Stamen Toner
- Stamen Watercolor
At the time of writing, I didn’t have API credentials for Mapbox Bright or Mapbox Control Room. But I’m assuming they still work if you have the appropriate API credentials.
Excluding the Mapbox tiles, those packaged by default are more than sufficient:
Tip: Read more on Stamen here, s'il vous plaît. They seem to be the original creators of these Stamen tiles.
Python + Folium + ORDS = Happiness
Folium installation and quick start pages are straightforward – requiring minimal steps and effort. The same goes for installing the Live Server extension too. Once installed, you can right-click on a .html file to load it onto a local development server (so it displays in a new browser window).
Let me jump right into how I set up Folium to work with ORDS. If you recall, most of the tables I have in my Autonomous Databases are REST-enabled (previous post working with ORDS).
An ORDS Review
…and now back to your regularly scheduled blog post
Since I needed latitude and longitude coordinates for Folium, I decided to work with my Restaurant table. Put the REST endpoint (URI) directly into the browser; and you’ll see this:
Afterward, I looked at the JSON object to see how it was structured (there are too many lists, dictionaries, arrays, etc. to remember amirite?!) because I’d need to iterate through all the items in the GET Response – to tease out what Folium needs.
The play-by-play
Printing the response (to see what it looks like)
- I’m covering all my bases here; reviewing the ORDS-provided request/object from a table in my Autonomous Database
- Using
json.()
to “decode” it into a python dictionary - Please pay attention to line 10, where I actually create the base map
Review of what Folium needs
- Looping through the python dictionary, pulling out what I need for the next step
- Including lines 25-29 to create the pop-up markers.
- The
('<i>{}</i>'.format(Resty))
allows me to pass the names to the string (stuff in quotes, plus the{}
). The HTML for italics is optional. - In this case, ‘x’ and ‘y’ are the coordinates
- Line 31 saves a .html file (which uses Bootstrap!)
Newly rendered .HTML
NOTE: This isn't the focus, but spoiler alert, I'll be putting this into a Flask application. I'll also build this out, so the individual markers/popups have charts/graphs for each restaurant. Again, all of which will be provided by ORDS-enabled tables (not so shameless plug).
Summary
After it is all said and done, it took me less than an afternoon to figure out how to make this work. So if you have a table with latitude and longitude, what are you waiting for?! REST-enable it with ORDS, and you can come up with a very quick demo on your own!
Also, I didn’t have to create any database models, the dependencies are minimal (a few python libraries), and an Always Free OCI account is really all you need to get started.
Code
import json
import requests
import folium
m = folium.Map(location=[35.78742648626059, -78.78122033558192], zoom_start=12, tiles="Stamen Watercolor")
response = requests.get('your ORDS enpoint/URI').json()
# print(type(response))
# print(response)
for entry in response['items']:
Resty = entry['name']
Lat = entry['y']
Long = entry['x']
folium.Marker(
location=[Lat, Long],
popup = folium.Popup('<i>{}</i>'.format(Resty))
#this line is optional/an alternative to the above line
# popup = folium.Popup('<i>{}</i>'.format(entry['name']))
).add_to(m)
m.save("index.html")
[I did not] reinvent the wheel
Lastly, much of what I learned about Folium came from the following two videos (I recommend bookmarking them for reference):
- Full Folium + Python playlist from franchyze923
- Excellent Folium walkthrough from Traversy Media