3

I have the following code.

models.py

class PFT(models.Model):

    species=models.CharField(max_length=50)
    geom = models.PointField(srid=4326)
    objects=models.GeoManager()
    def __str__(self):              
        return '%s %s %s' % (self.species, self.geom.x, self.geom.y)

views.py

def geojson_provinces(request):
    conn = psycopg2.connect(dbname="geodjango",host='localhost',user='postgres', password='postgres', port=5433)
    dict_cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    cur=conn.cursor()
    res = dict_cur.execute("SELECT ST_AsGeoJson(geom) AS json FROM pft_pft LIMIT 10;")

    points=dict_cur.fetchall()

    json_res  = []
    for row in points:
        json_obj  = row['json']
        json_res.append(json_obj)
        print(json)
    #json = simplejson.dumps(data)
    dict_cur.close()
    return render_to_response('map.html',
                          {'json_res': json_res},
                         context_instance=RequestContext(request))

urls.py

url(r'^geojson/$', geojson_provinces, name='geojson_provinces'),

Javascript code in map.html

<script>

    var map = new ol.Map({
       layers: [
          new ol.layer.Tile({
             source: new ol.source.OSM()
          })
       ]
       , target: 'map'
       , view: new ol.View({
          center: [0, 0]
          , zoom: 2
       })
    });

    var vectorSourceJsonp = new ol.source.Vector({
       format: new ol.format.GeoJSON()
       , loader: function(extent, resolution, projection) {        
          $.ajax({
             url: "{% url 'geojson_provinces' %}"
             , dataType: 'jsonp'
          });
       }
       , strategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({
          maxZoom: 19
       }))
       , projection: 'EPSG:4326'
    });
    // Executed when data is loaded by the $.ajax method.
    var loadFeatures = function(response) {
       vectorSourceJsonp.addFeatures(vectorSourceJsonp.readFeatures(response));
    };
    // Vector layer
    var vectorLayerJsonp = new ol.layer.Vector({
       source: vectorSourceJsonp
       , style: new ol.style.Style({
          stroke: new ol.style.Stroke({
             color: 'green'
             , width: 2
          })
       })
    });
    var mapJsonp = new ol.Map({
       target: 'mapJsonp'
       , renderer: 'canvas'
       , layers: [osmLayer, vectorLayerJsonp]
       , view: new ol.View({
          center: [-75.923853, 45.428736]
          , maxZoom: 19
          , zoom: 11
       })
    });

</script>

When I run http://localhost:8000/geojson only map is getting displayed but not the GeoJSON data as points.

  • Can you post your geojson? – Stefan Jan 7 '16 at 12:04
  • my geojson data is ["{\"type\":\"Point\",\"coordinates\":[76.996944,31.58]}", "{\"type\":\"Point\",\"coordinates\":[76.670778,31.487083]}", "{\"type\":\"Point\",\"coordinates\":[77.253,30.651722]}", "{\"type\":\"Point\",\"coordinates\":[76.672944,31.48325]}", "{\"type\":\"Point\",\"coordinates\":[76.669306,31.456861]}", "{\"type\":\"Point\",\"coordinates\":[76.587101,31.451527]}", "{\"type\":\"Point\",\"coordinates\":[76.590461,31.598462]}", "{\"type\":\"Point\",\"coordinates\":[76.554306,31.607389]}", "{\"type\":\"Point\",\"coordinates\":.. – Bruce Jan 7 '16 at 12:08
0

Instead of running raw sql querries, you should use the geodjango api that does the work for you. There is a geojson serializer that does exaclty what you want, see the docs here.

views.py

from django.core.serializers import serialize
from myapp.models import PFT

def geojson_provinces(request):
    first10_serialized = serialize(
        'geojson',
        PFT.objects.all()[:10],
        fields=('species', ),
    )
    return render_to_response(
        'map.html',
        {'json_res': first10_serialized},
        context_instance=RequestContext(request)
    )

This create valid geojson in your view's response. I am not familiar with openlayers so can't tell if you also have some problems in your javascript.

  • When I use the above code I'm getting the following result where geometry is null {"type": "FeatureCollection", "crs": {"type": "name", "properties": {"name": "EP SG:4326"}}, "features": [{"type": "Feature", "geometry": null, properties": {"species": "Pinus roxburghii Sargent"}}, {"type": "Feature", "geometry": null, "properties": {"species": "Pinus roxburghii Sargent"}}, {"type": "Feature", "geometry": null, "properties": {"species": "Pinus roxburghii Sargent"}}, {"type": "Feature", "geometry": null, "properties": {"species": ... – Bruce Jan 7 '16 at 13:54
  • C:\Python34\lib\site-packages\django\shortcuts.py:45: RemovedInDjango110Warning: The context_instance argument of render_to_string is deprecated. using=using) – Bruce Jan 7 '16 at 13:57
  • I updated the answer, try removing the geometry_field argument. If you dont have data, it could mean that you have rows that don't have a geometry. Try also PFT.objects.filter(geom__isnull=False)[:10]. What does print [dat.geom for dat in PFT.objects.all()[:10]] return? – yellowcap Jan 7 '16 at 14:23
  • print [dat.geom for dat in PFT.objects.all()[:10]] returns <generator object <genexpr> at 0x04572530>. And my table has rows with geometry – Bruce Jan 7 '16 at 14:32
  • The print is not very useful like this, the goal was to see the geometries. Could you try for dat in PFT.objects.all()[:10]: print dat.geom? – yellowcap Jan 7 '16 at 14:56
0

I think you need to parse your GEOJSON string. You can do it with the following code:

var obj = JSON.parse(json);

The obj variable contains the parsed GEOJSON. You can check the validity of your data on http://geojsonlint.com/

Change the following code to parse the response:

var loadFeatures = function(response) {
    vectorSourceJsonp.addFeatures(vectorSourceJsonp.readFeatures(response));
};

into:

var loadFeatures = function(response) {
    vectorSourceJsonp.addFeatures(vectorSourceJsonp.readFeatures(JSON.parse(response)));
};
  • Please could you let me know in which part of the code I must parse – Bruce Jan 7 '16 at 14:38
  • I changed accordingly but still data is not getting displayed. In the command line Im getting 'The context_instance argument of render_to_string is deprecated. using=using)' – Bruce Jan 7 '16 at 14:54
  • Have you tried the solution provided by @yellowcap? – Stefan Jan 7 '16 at 14:57
  • Yes. In that solution m getting geometry as null even though there is geometry in the table – Bruce Jan 7 '16 at 14:59
  • Unfortunately I cannot help you any further. Good luck – Stefan Jan 7 '16 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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