Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display Polygon in Leaflet Map from Geodjango Model

I'm developing a geospatial mapping application using geodjango and django-leaflet which lets users draw a polygon on a map and save that polygon to a model. I thought it would be simple to extract the saved polygon from the model and render it on a Leaflet map embedded in a template. However, I'm having considerable difficulty doing so. This is mostly due to me being a new web developer (I'm especially new to JS). Here's what I have so far:

models.py:

class newJob(BaseModel):
    job_name = models.CharField(max_length=64)
    job_desc = models.CharField(max_length=64)
    job_loc = models.PolygonField()
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

The spatial data is saved successfully to the model using the form I have created (not shown). I have then created a simple function-based view to pull the required data from the database. I have created a 'raw' object (job_loc) and also serialized the data to geojson to create json_loc (as I'm not sure which is best to work with).

views.py:

def viewjob(request):

        req = request.GET

        job_name = newJob.objects.values_list('job_name', flat=True).get(pk=req['search'])
        job_desc = newJob.objects.values_list('job_desc', flat=True).get(pk=req['search'])
        job_loc = newJob.objects.values_list('job_loc', flat=True).get(pk=req['search'])

        json_loc = newJob.objects.filter(pk=req['search'])
        json_loc = serialize('geojson', json_loc, geometry_field='job_loc')
        context = {

        'job_name': job_name,
        'job_desc': job_desc,
        'job_loc': job_loc,
        'json_loc': json_loc

        }

        print(context)

        return render(request,'viewjob.html', context)

And the code in my template. I was hoping that I could pass job_loc or json_loc to leaflet and be done with it (given everything I'm working with is geospatial), but that's clearly not the case.


  {{ json_loc }}
 
  {{job_loc}}

  <script type="text/javascript">
      function map_init(map, options) {
          // zoom to point
          map.setView([51.9923, -2.1580], 12);

          // get polygon
          var polygon = "{{ json_loc }}";
          var polygon = L.polygon(polygon).addTo(map);
      }
  </script>


  {% leaflet_map "yourmap" callback="window.map_init_basic" %}

Here is a screenshot if I render the above code (might be helpful to see the data that's returned from json_loc and job_loc, respectively): enter image description here

I've heard that Ajax might be a potential solution here, but I'm unsure on how to implement this. I was expecting to load the data into the map directly without using an Ajax call (i.e. the polygon is passed from the view on page render, then inserted into the map directly).

Can anyone guide me on the best way to acomplish this?

like image 348
Simon Avatar asked Nov 01 '25 08:11

Simon


1 Answers

Use the json_script tag for this purpose.

{{ json_loc|json_script:"json-loc" }}

<script type="text/javascript">
  function map_init(map, options) {
    // zoom to point
    map.setView([51.9923, -2.1580], 12);

    // get polygon
    var polygonData = JSON.parse(document.getElementById('json-loc').textContent);
    var polygon = L.polygon(polygonData).addTo(map);
  }
</script>
like image 63
Simon Charette Avatar answered Nov 04 '25 08:11

Simon Charette