1

I'm doing a project using the combination of GeoDjango, PostGIS, and OpenLayers

So far, I've imported OSM data with osm2pqsql, done settings and I knew the data is constructed by planet_osm_line, planet_osm_polygon, etc.

Now, I want to query all the villages boundaries under certain city and render with OpenLayers, I know I have to get the GeoJSON from the database and pass it to the template, but I have no idea how to make the queries using GeoManager, can somebody give me some instructions

Note: English is not my mother language, I try my best to explain my question

  • Welcome to GIS.SE! I think it's clear what you ask. Perhaps someone will edit your question to improve the language; I'm not a native English speaker, like you, so I'll leave this to others. I recommend you to read our tour page to learn basics of using this site. – Pavel V. Nov 10 '15 at 18:52
  • haha thx for your introduction – wtichentw Nov 11 '15 at 5:10
1

To filter your model instances with a polygon boundary, you can use the intersects lookup. So for instance

from django.contrib.gis.geos import Polygon
from myapp.models import MyVillages

poly = Polygon(((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)))
villages = MyVillages.objects.filter(geom__intersects=poly)

The villages queryset will then be a list of MyVillage models of which the boundaries overlap with the query polygon (assuming your geometry field is called "geom").

To pass the data to your template, it depends on how you construct your map with openlayers, so you would probably run the query above within a view and return the villages queryset to the template as a context variable.

Another option would be to use the django-rest-framework to create an api endpoint and then query that directly through javascript, see this answer for more information.

Edit - Example for MyVillage model:

from django.contrib.gis.db import models

class MyVillage(models.Model):
    name = models.CharField(max_length=500)
    osmid = models.IntegerField()
    geom = models.MultiPolygonField()
    objects = models.GeoManager()

Then you can also filter by the osm id of course. Note that this is not a geographic query and the get method will give an error if the osmid does not exist in the database:

single_vilage = MyVillage.objects.get(osmid=3802015)

or if you want to see if it exists

MyVillage.objects.filter(osmid__in=3802015).exists()
  • thx for your solution, I'll try it. I have one more question about constructing the model, should I always have GeometryField in my model, and how does your "MyVillage" actually looks like? cause now I am tring to query, while my model can map to the database, btw, I've set the postgis db in settings.py – wtichentw Nov 17 '15 at 16:52
  • how could I query with specific osm_id, qs = Unit.objects.filter(___=-3802015).geojson() the number is the osm_id i would like to query, but I dont know how to query with geometryfield – wtichentw Nov 17 '15 at 17:00
  • I updated the answer with an example for the model, you can store the osmid as a normal integer field. – yellowcap Nov 17 '15 at 17:35
  • yah, I got the error you mentioned, matching query does not exist., I've specified the DB in settings.py, but I don't know how to map the GeoDjango model to the DB, and I can't get why I don't need to specify the TABLE NAME, it's odd for me and what if I need to join two table ? thx for the advice by the way – wtichentw Nov 17 '15 at 18:20
  • If your table already exists, you need to tell Django that it does not have to manage it, see docs.djangoproject.com/en/1.8/ref/models/options/#managed. Otherwise you would have to create a migration and migrate the database, see docs.djangoproject.com/en/1.8/topics/migrations. Its seems like you are new to Django, maybe try to follow the introduction tutorial for some of those details docs.djangoproject.com/en/1.8/intro/tutorial01 – yellowcap Nov 18 '15 at 8:09

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.