2

I have begun to use Folium to publish some maps inside a GUI. The user is able to enter start and end coordinates and they show up as Folium Markers. I know that Folium library is just a wrapper around Leaflet, so could we use the parent library for methods that do not exist in Folium?

For instance, I want to use Leaflet.LatLng.distanceTo method to calculate the distance between start and end coordinates using the implemented spherical law of cosines. How I could use them inside my .py files?

I Attached this example code to represent where I'm stuck:

       .
       ..
       ...
       self.map = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
       ..
       ..
        self.m = folium.Map(
            location=[32.5236, 54], tiles="Stamen terrain", zoom_start=5, control_scale= True,
            box_zoom= True)

        # adds the markers
        self.marker1 =  folium.Marker((lat_1, lng_1)).add_to(self.m)
        self.marker2 =  folium.Marker((lat_2, lng_2)).add_to(self.m)

        #add above to the map
        self.data = io.BytesIO()
        self.m.save(self.data, close_file=False)
        self.map.setHtml(self.data.getvalue().decode())
        self.m.add_child(folium.LatLngPopup())

        """ 
        Enter the JavaScript Leaflet
        {
         Here I want "Leaflet.distanceTo((lat_1, lng_1), (lat_2, lng_2))" method
         }
        """

One of the other disadvantages of Foilum is the inability to remove map elements such as the start marker that the user wants to edit (this part's irrelevant, I'm only saying it to make you more familiar with the situation). It would be really good to solve these using appropriate Leaflet methods.

Any idea would be much obliged...

Ash
  • 263
  • 3
  • 14

1 Answers1

5

You can add any html, css or Javascript you want to a map. Here's an example of how to create a custom folium element and then overwrite its template.

el = folium.MacroElement().add_to(m)
el._template = jinja2.Template("""
    {% macro script(this, kwargs) %}
    // write JS here
    {% endmacro %}
""")

The script macro is a custom Jinja2 macro that makes sure the code within is placed in the script tags at the bottom of the page. Other options are header for the head and html for the body.

You can also access the name in Javascript of folium objects you made before:

popup = folium.LatLngPopup()
popup_js_name = popup.get_name()

Since it seems you already know a bit about folium and Leaflet I hope this is enough to help!

Conengmo
  • 783
  • 7
  • 13
  • Thank you or your answer @Conengmo. Is your solution possible when you are working on a PyQt5 GUI and not a webpage? And more importantly, how I could find more about these kinds of modifications? I very appreciate it :) – Ash Nov 11 '19 at 16:45
  • I didn't try folium with PyQt5, but I assume this approach will work generally. You can find out more possible hacks by reading the source code. If you're in Pycharm, or another capable IDE, you can control + click any function or class and read its code. At some point we should incorporate the most common hacks into folium properly. – Conengmo Nov 12 '19 at 15:05
  • How can I get the values in the JS code, for python variables? – AnonymousUser Nov 09 '21 at 04:09