title: How to extract a geometry from PostGIS using a view and then add it to a leaflet map in a template using Django
body: <p>I want to extract polygon geometry data from a PostGIS database using python within a view and add it to my leaflet map within a template.
  The easiest way seemed to be to extract the data and convert it to GeoJSON using the postgis function ST_AsGeoJSON in my Django view and then render it to the template as context within the L.geoJSON(GEOJSON).addTo(map) function.</p>
  
  <p>This does not work. On requesting the map page, the map is now blank and as it seems the GeoJSON is not recognised. I have been able to pass a hard-coded polygon from a view and add it to a map but the geometry data in my postgis database simply isn't valid.</p>
  
  <p>Here is a view with a hardcoded polygon that is successfully printed on the map:</p>
  
  <pre><code>from django.shortcuts import render
  
  def map_view(request, *args, **kwargs):
      geo_json={
          "type": "FeatureCollection",
            "features": [
              {
                "type": "Feature",
                "properties": {},
                "geometry": {
                  "type": "Polygon",
                  "coordinates": [
                    [
                      [
                        -0.10746002197265625,
                        51.505537109466715
                      ],
                      [
                        -0.11466979980468751,
                        51.498377681772325
                      ],
                      [
                        -0.0968170166015625,
                        51.493568479510415
                      ],
                      [
                        -0.09080886840820312,
                        51.502438390761164
                      ],
                      [
                        -0.10746002197265625,
                        51.505537109466715
                      ]
                    ]
                  ]
                }
              }
            ]
          }
  
      return render(request ,'map.html', {'geo_json': geo_json})
  
  </code></pre>
  
  <p>The map template looks as follows:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Map Page&lt;/title&gt;
      &lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" /&gt;
      &lt;script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"&gt;&lt;/script&gt;
      &lt;style&gt;
          #map {  position: relative;
                  width: 600px;
                  height: 775px;
                  border: 3px solid #000000;}
      &lt;/style&gt;    
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div id="map"&gt;&lt;/div&gt;
      &lt;script&gt;
          var map = L.map('map').setView([54.8,-4.45],6);
  
          L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=9GKOA9jJ3jCIWFUd8k00', {attribution: '&lt;a href="https://www.maptiler.com/copyright/" target="_blank"&gt;&amp;copy; MapTiler&lt;/a&gt; &lt;a href="https://www.openstreetmap.org/copyright" target="_blank"&gt;&amp;copy; OpenStreetMap contributors&lt;/a&gt;',}).addTo(map);
  
          L.geoJSON({{ geo_json | safe }}).addTo(map);
  
      &lt;/script&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/DIgRf.png" rel="nofollow noreferrer">Here is the leaflet map with the polygon added</a></p>
  
  <p>Now when I try to get pass GeoJSON from my postgis database using my new view it doesn't work:</p>
  
  <pre><code>import psycopg2
  from django.shortcuts import render
  
  def map_view(request, *args, **kwargs):
  
      connection = psycopg2.connect(database="electio5_geekdata",user="electio5_blake", password="dummypassword", host='localhost')
      cursor = connection.cursor()
      cursor.execute("select st_AsGeoJSON(shape) from boris_constituency limit 1")
      varpoly=cursor.fetchall()
  
      geo_json={
          "type": "FeatureCollection",
            "features": [
              {
                "type": "Feature",
                "properties": {},
                "geometry": varpoly
              }
            ]
          }
  
      return render(request ,'map.html', {'geo_json': geo_json})
  </code></pre>
  
  <p>I notice that the format of the GeoJSON is slightly different when I output it:-</p>
  
  <p>IS FINE</p>
  
  <p>{'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'properties': {}, 'geometry': {'type': 'Polygon', 'coordinates' and so on and so on</p>
  
  <p>IS A PROBLEM</p>
  
  <p>{'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'properties': {}, 'geometry': [('{"type":"MultiPolygon","coordinates" and so on and so on</p>
  
  <p>The problematic GeoJSON has extra brackets and a quote preceding the second "type" key</p>
  
  <p>So my question is:-</p>
  
  <p>1/ Is it possible to reformat the problematic GeoJSON? I had difficulty stripping out the unwanted characters which wrap the list </p>
  
  <p>2/ Or can I extract just the co-ordinates and pass those to the relevant part of geo_json? </p>
  
  <p>3/ Or any way at all I can extract the polygon data from postgis and add it to the leaftlet map</p>
  
  <p>btw you may wonder why I'm using a cursor rather than using the Django model object which has a GeoJSON method. This approach gave me a GDAL error due to the libraries not being properly configured and is a problem for another day!</p>
  
  <p>Big thanks for your attention to this.</p>
  
  <p>Phil #anoobintrouble </p>