kiwis
kiwis

Reputation: 75

PostGis Polygon into leaflet map using django

My issue is that I have no idea how can I visualize a polygon stored in PostGIS into a leaflet map using django.

In the template I'm using this to plot the points :

  <script type="text/javascript">

      function map_init(map, options) {
        {% for each_model in loca %}

          var lon =   {{each_model.location.x}}
          var lat =   {{each_model.location.y}}


          map.setView([lat, lon], 2);

          L.marker([lat, lon]).bindPopup("{{each_model.name}}").addTo(map)

          {% endfor %}
          // get point lat and lon

          // zoom to point & add it to map
        ;
      }

  </script>

models.py

from __future__ import unicode_literals

from django.contrib.gis.db import models
from django.contrib.gis.geos import Point


class Shop(models.Model):
    name = models.CharField(max_length=100)
    location = models.PointField()
    address = models.CharField(max_length=100)
    city = models.PolygonField()

if I print {{loca.city}} it would print out the GEOS object as follows:

SRID=4326;POLYGON ((2.988282590688516 6............))

any idea how can I plot the polygons as I'm plotting the points?

UPDATE II :

Printing out what the model producing when using Shop.object.all()

<QuerySet [<Shop: Shop object (1)>, <Shop: Shop object (2)>, <Shop: Shop object (3)>, <Shop: Shop object (4)>]>

the database table looks like this storing polygons and points (x,y) enter image description here

I thought about using a query manually (in the view) but it didn't work (cursor.execute("SELECT ST_AsText(city) FROM trial2_shop;)

Using this code :

{% for each_model in loca %}

{{each_model.name}} <br>

{% endfor %}

the output is this :

HELLO 
PARIS 
France 
abc 

and then using this one :

{% for each_model in loca %}

{{each_model.city}} <br>

{% endfor %}

the output is this :

SRID=4326;POLYGON ((2.988282590688516 6.287501448673132, -2.724608033516236 4.362344411133384, -5.624998658112493 4.800392361058798, -9.316404907598319 4.62520548641869, -7.29492053288002 -2.927082610924476, 8.701173214893267 -0.8189537900473602, 9.667970089758358 3.573231060257538, 5.537110715333732 4.362344411133384, 2.988282590688516 6.287501448673132)) 
SRID=4326;POLYGON ((2.379232127237539 48.99532183070828, 1.835408885125764 48.778601581576, 2.489095408472194 48.61544474629894, 2.780233103744227 48.87985458449839, 2.379232127237539 48.99532183070828)) 
SRID=4326;POLYGON ((4.921880363732911 48.86996904931716, 13.00781786260736 44.28238994198036, -8.08593213445636 32.47943349940858, -25.31249463205829 49.55890707900826, 5.364418038408538e-06 58.4058966101036, -8.789057134358529 49.10068218084409, 4.921880363732911 48.86996904931716)) 
SRID=4326;POLYGON ((10.10742321469805 59.8969527006269, 16.34765758882955 60.31310053764656, 15.02929821401315 57.87662999493084, 12.39257946438035 57.92333496310473, 10.10742321469805 59.8969527006269))

so i'm sure what is stored is polygons, but plotting it in the Map template upon retrieval is the issue...

Upvotes: 0

Views: 2077

Answers (1)

John Moutafis
John Moutafis

Reputation: 23144

You essentially need to use the leaflet polygon documentation inside your template.
You will need 2 things for this to work:

  1. A list of a Polygon's coordinates:

    lst_coords = [[point.x, point.y] for point in shop_object.city]
    

    This will result in a list of lists/pairs of coordinates.

  2. Insert the list of coordinates into a leaflet polygon:

    L.polygon(lst_coords, {color: 'red'}).addTo(map);
    

Now let's apply the above into your example:

  1. Add a property into your model to return the list of coordinates (that is only for convenience):

    class Shop(models.Model):
        name = models.CharField(max_length=100)
        location = models.PointField()
        address = models.CharField(max_length=100)
        city = models.PolygonField()
    
        @property
        def city_coords_list(self):
             return [[point.x, point.y] for point in self.city]
    
  2. Integrate the above into the template:

    <script type="text/javascript">
    
      function map_init(map, options) {
        {% for each_model in loca %}
    
          L.polygon(
            {{ each_model.city_coords_list }}, {color: 'red'}
          ).bindPopup({{ each_model.name }}).addTo(map)
    
      {% endfor %}
      // Find a way to fit the map accordignly (search the docs)
      ;
    }
    

Upvotes: 1

Related Questions