Skill - Draw text on python folium maps using DivIcon
Skills Required
- Setup python development environment
- Basic Printing in Python
- Commenting in Python
- Managing Variables in python
- Introduction to Folium for interactive maps in python
- Inject HTML into python folium maps
Please make sure to have all the skills mentioned above to understand and execute the code mentioned below. Go through the above skills if necessary for reference or revision
See this post to learn about folium libary basics
- Text can be drawn on the map using markers.
- While creating a marker, use
DivIcon
as the marker icon - HTML can be used as the DivIcon content. So we can write the desired text in the DivIcon, to achieve the text-marker effect
- Since the content of a DivIcon is HTML, we can even style the text using injected CSS. Injecting CSS into folium maps can be seen here
Example
# import folium library
import folium
mapObj = folium.Map(location=[24.2170111233401, 81.0791015625000],
zoom_start=5)
folium.Marker(location=[24.2170111233401, 81.0791015625000],
popup=folium.Popup('<i>The center of map</i>'),
tooltip='Center',
icon=folium.DivIcon(html="""Hello World <b>ABCDEFG</b>""",
class_name="mapText"),
).add_to(mapObj)
# inject html into the map html
mapObj.get_root().html.add_child(folium.Element("""
<style>
.mapText {
white-space: nowrap;
color:red;
font-size:large
}
</style>
"""))
mapObj.save('output.html')
Text that reacts to map zoom
- If we want to change the font size of the text based on the map zooming, we can create an event handler based on the map
zoomend
event to update the text font size based on the map zoom level. - This behavior has to be injected as JavaScript in the output HTML file
- For attaching the event handler to the map object, the JavaScript variable name of map object is required. We can get the JavaScript map object variable name in python using
mapObj.get_name()
- The JavaScript variable name can be derived in python and used in the injected JavaScript code
# import folium library
import folium
mapObj = folium.Map(location=[24.2170111233401, 81.0791015625000],
zoom_start=5)
folium.Marker(location=[24.2170111233401, 81.0791015625000],
popup=folium.Popup('<i>The center of map</i>'),
tooltip='Center',
icon=folium.DivIcon(html="""Hello World""",
class_name="mapText"),
).add_to(mapObj)
# get map variable name in output html
mapJsVar = mapObj.get_name()
# inject html into the map html
mapObj.get_root().html.add_child(folium.Element("""
<style>
.mapText {
white-space: nowrap;
color:red;
font-size:large
}
</style>
<script type="text/javascript">
window.onload = function(){
var sizeFromZoom = function(z){return (0.5*z)+"em"}
var updateTextSizes = function(){
var mapZoom = {mapObj}.getZoom();
var txtSize = sizeFromZoom(mapZoom);
$(".mapText").css("font-size", txtSize);
}
updateTextSizes();
{mapObj}.on("zoomend", updateTextSizes);
}
</script>
""".replace("{mapObj}", mapJsVar)))
mapObj.save('output.html')
Video
The video for this post can be found here and here
Thank you for creating this content. If you have multiple text/labels on the map, it can become very cluttered, especially when zoomed out. The labels are taking a fixed size regardless of the zoom and can collide/overlap.
ReplyDeleteDo you have some solution to manage this problem? Perhaps, only to show the text/label at certain zoom levels? Or, to have the text remain a fixed size relative to the shape?
Thanks for any suggestions - my map is so ugly because of this issue.
Hi, thanks for your feedback. I have updated this blog post with an example that has responsive text size based on map zooming using injected JavaScript.
DeleteHope this helps, Cheers👍
Really helped me, thank you so much
ReplyDeleteThanks a lot for the encouraging feedback. We are happy that this content helped you. Please subscribe to this content and refer this content to your friends, Cheers👍
Delete