3

I used a nice plugin for python folium:

https://www.youtube.com/watch?v=rAicpbCUwco&ab_channel=SudoControl

but the problem is, that my saved geojson file has no properties.

enter image description here

I tried to inject JS to my folium code:

drawjs = """
map.on(L.Draw.Event.CREATED; function (e) {
var type = e.layerType,
layer = e.layer;
var title = prompt("Please provide the name", "default");
var value = prompt("Please provide the value", "undefined");
var id = x++
e.feature.setProperties({
'Id': id,
'Name': title,
'Value': value,
});
});
"""


draw = plugins.Draw(
  drawjs,
  export=True,
  filename='drawing.geojon',
  position='topleft'
)
map.add_child(draw)

Unfortunately, I have an error:

<module>
draw = plugins.Draw(
TypeError: __init__() got multiple values for argument 'export'

which means, that I've used the wrong argument for attaching the JS code to my plugin.

How can it be sorted out?

UPDATE:

After solving an issue here:

https://stackoverflow.com/questions/74536711/python-folium-problem-with-editing-draw-plugin

I am on the right track to sorting it out. The piece of code where an error occurs looks like this:

 var {{ this.get_name() }} = new L.Control.Draw(
            options
        ).addTo( {{this._parent.get_name()}} );
        {{ this._parent.get_name() }}.on(L.Draw.Event.CREATED, 
    function(e) {
            let x = 1 // defining autoincrement ID
            var layer = e.layer,
                type = e.layerType;
            var title = prompt("Please provide the name", "default");
            var value = prompt("Please provide the value", 
          "undefinied");
            var id = x++
            var coords = JSON.stringify(layer.toGeoJSON());
            {%- if this.show_geometry_on_click %}
            layer.on('click', function() {
                alert(coords);
                console.log(coords);
                e.feature.setProperties({
                'Id': id,
                'Name': title,
                'Value': value,
                });
            });
            {%- endif %}
            drawnItems.addLayer(layer);
         });

where the JS console error states:

Uncaught TypeError: Cannot read properties of undefined (reading 'setProperties')
5
  • The first argument of Draw should be export. Your line is the same with Draw(export=drawjs, export=True,..). The error says 'you pass multiple export argument to Draw'. You need to inject the JS script to html page, not passing to Draw. Nov 25, 2022 at 10:21
  • ok, so do you mean I need to use ninja2 template and macros then?
    – Geographos
    Nov 25, 2022 at 10:33
  • You can use map element to add the JS script to html. I will add an answer. Nov 25, 2022 at 11:03
  • Hmm, I think I've already found a track and fighting with an error, maybe will be better to update an answer by myself first.
    – Geographos
    Nov 25, 2022 at 11:10
  • I guess there is no setProperties method for feature. Nov 25, 2022 at 11:29

1 Answer 1

8
+100

The JS script to be used in Python code:

$(document).ready(function(){           
    var x = 0;
    
    // {map} will be replaced to map object using Python
    {map}.on("draw:created", function(e){

        // get layer and feature    
        var layer = e.layer;
            feature = layer.feature = layer.feature || {}; 
        
        // user input
        var title = prompt("Please provide the name", "default");
        var value = prompt("Please provide the value", "undefined");
        var id = x++;

        feature.type = feature.type || "Feature";
        var props = feature.properties = feature.properties || {};

        // set properties
        props.Id = id;
        props.Title = title;
        props.Value = value;

        // add the drawn feature to the layer
        drawnItems.addLayer(layer);
      });    
    });

You need map.get_root().html to get html, and add_child method to add JavaScript to the page.

import folium
from folium.plugins import Draw

m = folium.Map()

Draw(export=True,
     filename='drawing.geojson',
     position = 'topleft').add_to(m)

mapObjectInHTML = m.get_name()

m.get_root().html.add_child(folium.Element("""
<script type="text/javascript">
  $(document).ready(function(){           
    var x = 0;
    
    {map}.on("draw:created", function(e){    
        var layer = e.layer;
            feature = layer.feature = layer.feature || {}; 
            
        var title = prompt("Please provide the name", "default");
        var value = prompt("Please provide the value", "undefined");
        var id = x++;

        feature.type = feature.type || "Feature";
        var props = feature.properties = feature.properties || {};
        props.Id = id;
        props.Title = title;
        props.Value = value;
        drawnItems.addLayer(layer);
      });    
    });    
</script>
""".replace('{map}', mapObjectInHTML)))

m

enter image description here

drawing.geojson for the image above:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "Id": 0, "Title": "default", "Value": "undefined" },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-48.515625, 11.178402],
            [30.9375, 48.922499],
            [58.359375, -13.239945],
            [-48.515625, 11.178402]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": { "Id": 1, "Title": "default", "Value": "undefined" },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [7.03125, 55.776573],
            [-56.953125, 26.431228],
            [-87.1875, 64.168107],
            [7.03125, 55.776573]
          ]
        ]
      }
    }
  ]
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.